【问题标题】:Ruby regex - single match across linesRuby 正则表达式 - 跨行单匹配
【发布时间】:2018-10-06 12:57:53
【问题描述】:

我的计划:

  1. 获取Send to: 和该行末尾之后的所有内容。
  2. 获取Attn: 和该行末尾之间的所有内容。

注意:Attn 行可以是可选的。在这种情况下,只需返回第一行。

字符串如下所示:

str = <<-MSG
Registry of Credit Recommendations
American Council on Education
One Dupont Circle, NW
Washington, D.C. 20036
Transcript Print Date: 10/03/2018
Sent By:Send To: American University
4400 Massachusetts Avenue, NW
Washington, DC 20016-8001
Attn: Undergraduate Admissions
Jonathan A Jones
30 People's Court
Second Address Line
Third Address Line
Augusta, GA 30909
MSG

预期的返回值必须是:

American University
Attn: Undergraduate Admissions

**注意必须包含“Attn:”部分,而不仅仅是它的内容。 **

这是我的方法,仅适用于 Attn 部分,但我不知道如何获得“美国大学”部分。

regex = /Attn:([^\r\n]+)[\r\n]+/

测试:http://rubular.com/r/Px4ru6WrAg

感谢您的帮助。

【问题讨论】:

  • @SebastianPalma 当我运行您的解决方案 str.scan(regex) 它输出 ["American University", "Undergraduate Admissions"] 我只期待一个子字符串:["American University/n Attn : Undergraduate Admissions"] 还要注意 "Attn:" 部分包括在内。

标签: ruby regex multiline


【解决方案1】:

您可以使用alternation

(?&lt;=Send To:).*|Attn:.*

  • (?&lt;=Send To:) 肯定的后视断言左边是Send To:。然后匹配任意字符一次或多次
  • |
  • Attn:.+ Match Attn: 后跟任意字符一次或多次

Regex demo

【讨论】:

  • 抱歉,您的解决方案的输出与预期的输出有很大不同。
  • 您的值在第一个捕获组中。
  • @victorhazbun 所以你的意思是Send To:\K.*|Attn:.* Demo
  • @victorhazbun 啊,我明白了,这应该可以工作(?&lt;=Send To:).*|Attn:.*Test
  • @victorhazbun 您不能将两个单独的匹配项连接到一个捕获组中。
【解决方案2】:

请注意,您不必使用正则表达式。

str.each_line.
    map do |line|
      case
      when line.include?("Send To: ")
        line[line.index("Send To: ") + "Send To: ".size..-2]
      when line.include?("Attn: ")
        line[line.index("Attn: ")..-2]
      else
        nil
      end
    end.compact
      #=> ["American University", "Attn: Undergraduate Admissions"]

-2 不包括结束每一行的换行符。

【讨论】:

    最近更新 更多