【问题标题】:Regex to split lines in javascript正则表达式在javascript中分割行
【发布时间】:2013-06-02 17:36:25
【问题描述】:

我想在 Javascript 中将以下几行拆分成一个数组:

Jun 02 16:45:04 [steveh]  [info] test1
Jun 02 16:45:12 [steveh]  [info] test2
Jun 02 16:45:12 [steveh]  [info] test3
test 3.1
test 3.2
Jun 02 16:45:16 [steveh]  [info] test4

我可以这样做:

var arr = data.split(/\r?\n/);

这让我明白了:

[
    "Jun 02 16:45:04 [steveh]  [info] test1",
    "Jun 02 16:45:12 [steveh]  [info] test2",
    "Jun 02 16:45:12 [steveh]  [info] test3",
    "test 3.1",
    "test 3.2",
    "Jun 02 16:45:16 [steveh]  [info] test4"
]

到目前为止一切顺利,但问题是,我不想要该数组中的 6 个项目,我只想要 4 个这样的东西:

[
    "Jun 02 16:45:04 [steveh]  [info] test1",
    "Jun 02 16:45:12 [steveh]  [info] test2",
    "Jun 02 16:45:12 [steveh]  [info] test3
    test 3.1
    test 3.2",
    "Jun 02 16:45:16 [steveh]  [info] test4"
]

我用 js 的 .match().split() 函数玩了一段时间,但没弄明白。

这里是 jsbin:http://jsbin.com/icufef/1/edit

【问题讨论】:

  • 你从哪里得到这些数据?
  • 实际上来自一个返回服务器日志的网络服务。我想在 javascript 中过滤该日志,因此我需要一个数组。但是对于测试,您可以将其作为多行字符串处理。
  • 如果你知道你想要得到的确切格式,你可以尝试使用正则表达式来匹配该字符串而不是拆分。 Online demo

标签: javascript regex arrays split match


【解决方案1】:

在拆分中使用以下 RE:

 /\r?\n(?=[^\n]*\[info\])/

仅当以下行包含 [info] 时才在换行符处拆分。

【讨论】:

    【解决方案2】:

    除非您对日期的格式有所了解,否则通常无法执行此操作...好吧,我想如果您跳过日期并将其基于 [steveh] [info] 对,您可能会找到解决方案。但是test 3.1 等呢?什么可能的数据可以进入那里?可以有带括号的文字吗?能有约会吗?在不知道这些数据的结构的情况下,您愿意走多远来确保对其进行合理的解析?

    总是有可能想出大部分正确解析它的解决方案,但会错过一些场景。

    根据数据,这些情况可能会使数据无法正确解析,也就是说,如果记录器记录的行还包含看起来像新日志行的行,例如“foo\nJun 02 16:47 :16 [steveh] [info] test4" 并且该字符串中给出的日期恰好是发生在连续日志记录之间的日期,仅通过查看日志数据就不可能将该行与其他日志行分开.

    【讨论】:

    • 我同意没有错误的可能性是不可能的。一个人必须忍受这种风险。如果日志格式可以“调整”(配置),可以尝试在日志格式中找到一个好的开始标志。
    • 好吧,如果 Web 服务本身(OP 提到的)使用一些约定来分隔日志文件,并为您分隔,那么就没有必要讨论这个了——除非也许它所犯的错误是无法容忍的。相反,任何想要使用此 Web 服务的人都必须制作自己的糟糕解析器,然后,如果记录器更改其格式,使用该服务的每个人都必须修复他们的解析器。我可以看到有人可能想要使用 Web 服务公开原始日志文件的正当理由,但互操作性不在其中。
    • 每当我看到这样的问题时,我都想知道,如果通过帮助,我只是在帮助修补一艘应该已经沉没的注定失败的船,而每个人都会过得更好船已经沉没了.
    【解决方案3】:

    您必须搜索换行符,后跟一个月份短名称,因此它将类似于 \r?\n(Jan|Feb|March|Apri...|Dec) 作为拆分参数。您需要知道您的数据如何提供这些月份名称,而不是“测试”而不是“可能”来捕捉它。

    编辑: 哦,Xavier 是对的:您应该将这些条目标记为真正的换行符,而不是将其输入拆分:

    data.replace('/^(Jan|Feb...) /', 'BREAKME$1');
    data.split('/\r?\nBREAKME');
    

    【讨论】:

    • 但这不会从输出中删除月份名称吗?
    • 您需要在该组中添加一个前瞻 :) 之后,我认为它就像 OP 想要的那样工作。
    • 像这样添加?=\r?\n(?=Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
    • 我不得不承认:通常我只是在一个循环中结束:只要没有“真正的新行”出现,我就将行添加到最后一个 var,当“真正的新行” line" 来了,我把最后一个 var 推到数组中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多