【问题标题】:Regex loop parsing with negative word lookahead带有负词前瞻的正则表达式循环解析
【发布时间】:2014-04-03 16:51:06
【问题描述】:

我正在尝试解析以下字符串,但我似乎无法弄清楚如何对单词使用正则表达式否定。我有以下短信历史记录。

string = '2014-03-29 10:29:24 AM: John Doe: Hey dude how are you feeling 2014-03-29 10:30:39 AM: Billy: Hey Doe, Im feeling better now. 2014-03-29 10:30:58 AM: Billy: Yup'

我的正则表达式 ruby​​ 查询目前如下所示:

string.scan(/((\d{4}-\d{2}-\d{2}\s+\d{2}\:\d{2}\:\d{2}\s+[AP][M])\:\s(.*?)\:\s([^\d{4}]*))/) {|match| puts match}

Output:
   2014-03-29 10:29:24 AM: John Doe: Hey dude how are you feeling 
   2014-03-29 10:29:24 AM
   John Doe
   Hey dude how are you feeling 
   2014-03-29 10:30:39 AM: Billy: Hey Doe, Im feeling better now. 
   2014-03-29 10:30:39 AM
   Hason
   Hey Doe, Im feeling better now. 
   2014-03-29 10:30:58 AM: Billy: Yup
   2014-03-29 10:30:58 AM
   Billy
   Yup

问题

我的正则表达式否定只适用于字符而不是单词。 [^\d{4}] 仅在检测到任何数字而不是“2014”之类的单词时才会停止。

【问题讨论】:

    标签: regex parsing regex-negation


    【解决方案1】:

    试试下面的。我使用?: 来避免从您的正则表达式中捕获少数组。此外,添加了一个积极的前瞻(?=\d{4}-|$),以查看下一个或其行尾是否有任何\d\d\d\d- 格式可用。如果你愿意,你可以把它改成你的模式(我的意思是把它变成yyyy-mm-dd 格式)。

    string.scan(/((?:\d{4}-\d{2}-\d{2}\s+\d{2}\:\d{2}\:\d{2}\s+[AP][M])\:\s(?:.*?)\:.*?)(?=\d{4}-|$)/) {|match| puts match}
    

    输出:

    2014-03-29 10:29:24 AM: John Doe: Hey dude how are you feeling 
    2014-03-29 10:30:39 AM: Billy: Hey Doe, Im feeling better now. 
    2014-03-29 10:30:58 AM: Billy: Yup
    

    【讨论】:

      【解决方案2】:

      你可以匹配所有直到一个特定的“单词”,例如单词“2014”:

      (?>[^2]+|2(?!014))*
      

      与未知年份相同(四位数):

      (?>[^0-9]+|[0-9](?![0-9]{3}-))*
      

      另一种方法是先行分割字符串:

      string.split(/(?=\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+[AP][M]:)/)
      

      注意:对于这三种模式,您可以选择如何指定前瞻断言中子模式的长度和精度。

      【讨论】:

        【解决方案3】:

        字符类不是这样工作的。

        [^\d{4}]*

        意思:

        ^    -  Negative class, so -
        \d   -  Not digit 0-9
        {    -  Not '{'
        4    -  Not '4'
        }    -  Not '}'
        

        而且,该类可以多次匹配此集合。
        因此,它会停止,并且不会匹配数字Not digit 0-9

        匹配直到一个4位数的单词也可以是这样的

         (                             # (1 start)
              (                             # (2 start)
                   \d{4} - \d{2} - \d{2} 
                   \s+ 
                   \d{2} \: \d{2} \: \d{2} 
                   \s+ 
                   [AP] [M] 
              )                             # (2 end)
              \: \s 
              ( .*? )                       # (3)
              \: \s 
              (                             # (4 start)
                   (?:
                        (?! \d{4} )              # Not 4 digits ahead of this character
                        .                        # Ok, match the character
                   )*
              )                             # (4 end)
         )                             # (1 end)
        

        【讨论】:

          猜你喜欢
          • 2020-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-11
          • 2011-10-14
          • 2010-12-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多