我正在尝试解析以下字符串,但我似乎无法弄清楚如何对单词使用正则表达式否定。我有以下短信历史记录。
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'”这样的词。
答案 0 :(得分: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
答案 1 :(得分:0)
您可以匹配所有特定的"字"像这样的例子,单词" 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]:)/)
注意:对于这三种模式,您可以选择在预测断言中使用子模式的长度和精度来特定的方式。
答案 2 :(得分:0)
角色类不会像这样工作。
[^\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)