我对regex有一个问题,使用preg_match_all()来匹配可变长度的内容。
我想要匹配的是“拥挤”这个词之后的交通状况,我想出的是这个正则表达式:
Congestion\s*:\s*(?P<congestion>.*)
但是,它将提取第一个实例,直到整个主题结束,因为.*将匹配所有内容。但这不是我想要的,我想让它分别作为3个实例来匹配。
现在,由于拥塞背后的单词可能是可变长度的,所以我不能真正预测出在中间有多少单词和空格来进行更严格的\w*\s*\w*匹配等等。
有什么线索让我从这里开始吗?
Highway : Highway 26
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow from Smith St to Alice Springs St
Highway : Princes Highway
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow at the Flinders St / Elizabeth St intersection
Highway : Eastern Freeway
Datetime : 18-Oct-2010 05:19 PM
Congestion : Traffic is slow from Prince St to Queen St编辑以实现清晰性
这里的这些格式非常好的文本,实际上是通过格式非常差的html电子邮件接收的。它包含随机的断线,例如“塞车:从王子\n到皇后街的交通很慢”。
因此,在处理电子邮件时,我去掉了所有html代码和随机换行,然后json_encode()将它们转换成一个非常长的单行字符串,没有中断.
发布于 2010-10-18 11:24:06
您可以尝试一个最小的匹配:
Congestion\s*:\s*(?P<congestion>.*?)
这将导致在命名组“拥塞”中返回零个字符,除非您可以在拥塞字符串之后立即匹配。
因此,如果“公路”总是启动交通状况记录,则可以修复这个问题:
Congestion\s*:\s*(?P<congestion>.*?)Highway\s*:
如果这是有效的(我没有检查它),那么第一个记录是匹配的,但最后一个记录是不匹配的!这可以很容易地通过在输入字符串的末尾附加文本‘高速路:’来解决。
发布于 2010-10-18 10:14:20
通常,正则匹配是基于线的.Regex假设您的字符串是一行。您可以使用“m” () flag来改变这种行为。然后,您可以告诉PHP只匹配行尾:
preg_match('/^Congestion\s*:\s*(?P<congestion>.*)$/m', $subject, $matches);有两件事需要注意:首先,模式被修改为包含了行开始(^)和行结束($)标记。其次,该模式现在带有m修饰符。
发布于 2010-10-18 10:13:45
Congestion\s*:\s*Traffic is\s*(?P<c1>[^\n]*)\s*from\s*(?P<c2>[^\n]*)\s*to\s*(?P<c3>[^\n]*)$https://stackoverflow.com/questions/3958133
复制相似问题