我在尝试应用以下正则表达式时遇到问题:
(1234).*?(abcd)?
到以下字符串:
1234567abcd
我的期望是上面应该产生两个匹配:
然而,这不起作用。您可能会建议“好吧,只需删除尾随的?
字符?” - 但我希望第二种模式是可选的。
这是怎么做到的?
重申:
(1234).*?(abcd)
...给出了所需的结果,但我搜索的字符串并不总是包含abcd
。
如果有人想知道,这是更大图片问题的简化示例。如果需要,我会解释一下。
====
我认为这个问题需要进一步澄清。这是我想要做的更完整的例子,在ruby中。
从我的日志文件中给出以下两个“doctored up”行:
Aug 28 00:00:05 app-system-1 app-prod[7660]: Completed 200 OK in 150ms (Views: 24.6ms | ActiveRecord: 66.1ms)
Aug 28 00:05:06 app-system-1 app-prod[10639]: Completed 302 Found in 81ms (ActiveRecord: 74.6ms)
我试图在ruby中编译正则表达式如下:
d=Regexp.new('(?<timestamp>\w{1,3}\s\d{1,2}\s\d\d:\d\d:\d\d).*(?<in>in [0-9]*).*(?<views>Views: [0-9]*).*(?<activerecord>ActiveRecord: [0-9]*)')
显然在某些情况下会包含'views'文本,在其他行中,它不存在。
我希望能够做到这样的事情:
v=d.match(line)
if !v.nil?
puts v[:timestamp]+ " " + v[:in] + " " + v[:views] + " " + v[:activerecord]
这显然是一个不完整的例子,但希望这可以澄清。
答案 0 :(得分:2)
您没有指定您想要的内容,至少不清楚,但我认为您需要以下内容:
...1234567abcd...
,则应匹配1234567abcd
,并应捕获1234
和abcd
。...1234567abce...
,则应匹配1234
,应捕获1234
。如果是这样,您可以使用:
/(1234)(?:.*?(abcd))?/s
我讨厌使用贪婪修饰符。它用于避免匹配某些序列,但不能保证它不会。我会用以下代码:
/
(1234)
(?:
(?:(?!abcd).)* # Safer than .*?
(abcd)
)?
/sx
答案 1 :(得分:1)
锚定正则表达式:
/(1234).*?(abcd)?$/
答案 2 :(得分:1)
与ikegami相似,但我认为更简单:
/(1234)(?:(?!abcd).)*(abcd)?/
答案 3 :(得分:0)
由于(a|)
大致相当于(a)?
,我们可以使用:
(1234).*?(abcd|)
强制正则表达式引擎先检查abcd
。具有?
的可选规则的默认值是假设它不存在(相当于(|abcd)
)。此默认行为对于确保正则表达式终止(更快)非常重要。
答案 4 :(得分:0)
你应该分步进行。
if (my ($ts, $dur, $breakdown) = /
^
(\w{3}[ ]\d{1,2}[ ]\d\d:\d\d:\d\d)
.*?
in[ ]([0-9]*)ms
.*?
\( ([^()]*) \)
/xs) {
my %breakdown = map /^([^:]+): (.*)ms/, split /\s*\|\s*/, $breakdown;
say join ', ',
$ts,
$dur,
$breakdown{Views} // '--',
$breakdown{ActiveRecord} // '--';
}