【问题标题】:Regex, how to match multiple lines?正则表达式,如何匹配多行?
【发布时间】:2011-07-11 12:46:33
【问题描述】:

我正在尝试将From 行一直匹配到以下Subject 行的末尾:

....
From: XXXXXX 
Date: Tue, 8 Mar 2011 10:52:42 -0800 
To: XXXXXXX
Subject: XXXXXXX
....

到目前为止我有:

/From:.*Date:.*To:.*Subject/m

但这与主题行的结尾不匹配。我尝试添加$,但没有效果。

【问题讨论】:

  • 您似乎知道多行,但您没有在数据样本中显示多行。我根本看不到任何多行。只有一根长长的绳子从:... 主题 XXXXX。这太简单了,无法为此编写正则表达式。为什么不提供准确的样本?
  • 不鼓励在 Stack Overflow 中使用“Hello”和“thxs”。 meta.stackexchange.com/questions/2950/…
  • @sln:数据样本确实有多行,但 OP 没有费心检查它的格式是否符合他的预期。
  • @Andrew Grimm - 在我发帖之前我已经猜到了。然而,在您修复 OP 的格式之前出现了 4 个答案。有点奇怪
  • @Andrew Grimm - 我知道这有利于在这里学习 SO,但似乎投票正在破坏该原则。

标签: ruby regex rubular


【解决方案1】:

如果您想跨换行符进行匹配,一种可能性是首先将所有换行符替换为文本中不会出现的其他字符(或字符序列)。例如,如果您将所有文本都放在一个字符串变量中,您可以执行aString.split("\n").join("|") 之类的操作,将字符串中的所有换行符替换为竖线字符。

另外,请查看 Alan Moore's answer 到您之前关于如何匹配正则表达式中的换行符的问题。

【讨论】:

  • 谢谢 bta,我不想替换换行符。有没有正则表达式方法可以做到这一点?
  • 不管使用什么方法,这似乎都是对正则表达式的丑陋使用。创建一个解析各个字段并将它们存储在成员变量中的类可能会更干净、更健壮。由于看起来您正在解析电子邮件,因此可能已经有一个类可以为您解析。
【解决方案2】:

试试:

/...^Subject:[^\n]*/m

【讨论】:

    【解决方案3】:

    使用以下数据:

    From: XXXXXX
    Date: Tue, 8 Mar 2011 10:52:42 -0800
    To: XXXXXXX
    Subject: XXXXXXX
    

    以下正则表达式将发挥作用:

    From:([^\r\n]+)[\r\n]+Date:([^\r\n]+)[\r\n]+To:([^\r\n]+)[\r\n]+Subject:([^\r\n]+)[\r\n]+
    

    但我建议您不要尝试在 1 个正则表达式中执行此操作。逐行推入正则表达式“^(\w+):(.+)$”,除非您确定 FROM/DATE/TO/SUBJECT 的顺序不会改变;)

    【讨论】:

    • 它会改变,有时可能会有额外的一行,例如 ON BEHALF OF,所以猜猜这​​行不通?
    • 最好是使用打破每一行的东西。
    • (抱歉,stackoverflow 的新手不知道输入提交评论:P)
    • 每条线都断了是什么意思?
    • 最好是使用打破每一行的东西,然后用 ":" 分隔,如 "^\s*(\w+)\s*:\s*(.+)\s*$ " 然后将匹配 1 作为关键字,将匹配 2 作为值。推入一个哈希然后检查你是否在解析结束时得到了你想要的。希望这会有所帮助
    【解决方案4】:

    您可以使用/m 修饰符启用多行模式(即允许. 匹配换行符),您可以使用? 执行非贪婪匹配:

    message = <<-MSG
    Random Line 1
    Random Line 2
    From: person@example.com
    Date: 01-01-2011
    To: friend@example.com
    Subject: This is the subject line
    Random Line 3
    Random Line 4
    MSG
    
    message.match(/(From:.*Subject.*?)\n/m)[1]
    => "From: person@example.com\nDate: 01-01-2011\nTo: friend@example.com\nSubject: This is the subject line"
    

    查看http://ruby-doc.org/core/Regexp.html 并搜索“多行模式”和“默认贪婪”。

    【讨论】:

    • 效果很好。使用这个有什么问题吗?其他两个答案似乎有点反对这种方法?
    • 我认为这种方法没有任何问题。具体细节实际上取决于您想要使用正则表达式捕获的内容。我认为要记住的主要事情是?运算符和 /m 开关。这两种技术将真正让您使用正则表达式来处理多行数据。
    • @AnApprentice- 主要缺点是使用正则表达式执行此操作对输入格式提出了非常严格的要求。此技术适用于此特定示例,但如果输入中有任何变化(字段的列出顺序等),它可能不起作用。我在使用覆盖多个输入行的单个正则表达式方面有过许多糟糕的经历,我通常鼓励使用更通用的非正则表达式解决方案。如果您的输入受到严格控制并且始终遵循这种精确格式,那么您应该能够使用这样的东西。
    • 您不应该仅仅因为输入的格式发生变化就排除正则表达式,您可能只需要修改表达式或以不同的方式提取数据。例如,如果您担心字段的顺序,那么您可以使用 4 个不同的正则表达式来分别捕获每条数据,而不是对所有数据(从、到、日期、主题)使用单个正则表达式。
    • 如果输入文本有多个主题。在第一次出现主题之前如何选择文本。
    【解决方案5】:

    如果你使用的是 ruby​​,你可以试试:

    Regexp.new("some reg", Regexp::MULTILINE)
    

    如果你不使用 ruby​​,我建议你破解这个问题:

    1. 将所有“\n”替换为 SOME_SPECIAL_TOKEN
    2. 搜索正则表达式,并进行其他操作...
    3. 恢复:将 SOME_SPECIAL_TOKEN 替换为“\n”

    【讨论】:

      猜你喜欢
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多