这个问题已经有一个答案在这里:

我有如下一行:

"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;([^;]*);([^;]*);([^;]*);(.*)/
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top