当前位置:  开发笔记 > 编程语言 > 正文

如何修复我的正则表达式与贪婪的量词不匹配?

如何解决《如何修复我的正则表达式与贪婪的量词不匹配?》经验,为你挑选了3个好方法。

我有以下几行:

"14:48 say;0ed673079715c343281355c2a1fde843;2;laka;hello ;)"

我使用一个简单的正则表达式解析这个:

if($line =~ /(\d+:\d+)\ssay;(.*);(.*);(.*);(.*)/) {
    my($ts, $hash, $pid, $handle, $quote) = ($1, $2, $3, $4, $5);
}

但是; 最后搞砸了,我不知道为什么.贪婪的操作员不应该处理"一切"吗?



1> Barry Brown..:

贪婪的运算符试图抓住尽可能多的东西,仍然匹配字符串.发生的事情是第一个(在"说"之后)抓住"0ed673079715c343281355c2a1fde843; 2",第二个采用"laka",第三个发现"你好"而第四个匹配括号.

你需要做的是让除了最后一个之外的所有人都非贪婪,所以他们尽量少抓住并仍然匹配字符串:

(\d+:\d+)\ssay;(.*?);(.*?);(.*?);(.*)


区别在于.*?停止在后面的任何内容的第一个实例,而.*停止在后面的任何内容的最后一个实例.
的?修改*运算符使其变得非贪婪.你也可以用?用+来使它不贪婪.
非常好的一般案例答案,但是,对于这个具体问题,我赞成[^;]*over.*?因为终止匹配的边界是单个字符.有些情况下.*?是你需要的,但我发现最好尽可能避免.*

2> VonC..:
(\d+:\d+)\ssay;([^;]*);([^;]*);([^;]*);(.*)

应该工作得更好



3> Tanktalus..:

虽然正则表达式很容易做到这一点,但我不确定它是最直接的方法.它可能是最短的,但实际上并不能使它成为最可维护的.

相反,我建议这样的事情:

$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 ;)]

我认为这只是更具可读性.不仅如此,我认为它也更容易调试和维护,因为如果人类用笔和纸尝试同样的事情,这更接近于你将如何做到这一点.将字符串分解成块,然后您可以更轻松地解析 - 让计算机完全按照您的方式执行操作.当需要进行修改时,我认为这个会更好.因人而异.

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有