我怎么能修复我的regex不匹配的太多了有一个贪婪的数量词?[重复]
-
05-07-2019 - |
题
这个问题已经有一个答案在这里:
我有如下一行:
"14:48 say;0ed673079715c343281355c2a1fde843;2;laka;hello ;)"
我分析,这可通过使用一个简单的regexp:
if($line =~ /(\d+:\d+)\ssay;(.*);(.*);(.*);(.*)/) {
my($ts, $hash, $pid, $handle, $quote) = ($1, $2, $3, $4, $5);
}
但;在结束混乱的东西,我不知道为什么。不应该贪婪的操作者处理"一切"?
解决方案
贪婪的操作者试图抓住作为多东西,因为它可以并且仍然相匹配。发生了什么是第一个(以后"说")抓住"0ed673079715c343281355c2a1fde843;2为",第二个需要"加拉卡",第三找到"你好"和第四匹配的括号。
你需要做的是使所有,但最后一个非贪婪,因此他们抢尽可能少和仍然相匹配的string:
(\d+:\d+)\ssay;(.*?);(.*?);(.*?);(.*)
其他提示
(\d+:\d+)\ssay;([^;]*);([^;]*);([^;]*);(.*)
应该更好地工作
虽然regex可以很容易地做到这一点,我不确定这是最直接的方法。它可能最短的,但这并不实际上使最易于维护。
相反,我建议是这样的:
$x="14:48 say;0ed673079715c343281355c2a1fde843;2;laka;hello ;)";
if (($ts,$rest) = $x =~ /(\d+:\d+)\s+(.*)/)
{
my($command,$hash,$pid,$handle,$quote) = split /;/, $rest, 5;
print join ",", map { "[$_]" } $ts,$command,$hash,$pid,$handle,$quote
}
这个结果:
[14:48],[say],[0ed673079715c343281355c2a1fde843],[2],[laka],[hello ;)]
我认为这只是一个位更具可读性。不仅如此,我认为这也更易于调试和维护,因为这是接近,你会怎么做,如果一个人都尝试同样的事情笔和纸。打破串下进入大块的,然后你可以分析更容易-拥有计算机做什么你会怎么做。当时候做出修改,我认为这个人会费更好。情况因人而异。
尝试使第3 (.*)
ungreedy (.*?)
如果值在你的分号分隔的清单无法包括的任何分号自己,你会得到最高效而简单的规则的表达简单地通过拼写出来。如果某些价值观只能说,一串hex字拼写出来。解决方案使用一个懒惰的或贪婪点将始终导致很多无用的回溯当regex不匹配的问题串。
(\d+:\d+)\ssay;([a-f0-9]+);(\d+);(\w+);([^;\r\n]+)
你可以让*非贪心通过附加问题:
$line =~ /(\d+:\d+)\ssay;(.*?);(.*?);(.*?);(.*)/
或者你可以相匹配的一切除了一个分号的每一部分,除了最后一个:
$line =~ /(\d+:\d+)\ssay;([^;]*);([^;]*);([^;]*);(.*)/
不隶属于 StackOverflow