0

我正在尝试使用以下内容解析字符串:

preg_match( "|from:(.*?);|", $string, $match);

但后来我发现字符串也可以包含lfrom:_from:

字符串如何的几个示例:

var1:34234;来自:website1.com;lfrom:website2.com;var2:343423; lfrom:website1.com;var1:4234234;from:website2.com from:website1.com;_from:website2.com;lfrom:website2.com;var1:43523;

我如何只解析from:(.*?);而不解析lfrom,_from

4

4 回答 4

1

您可以使用断言:

|(?<!l)from:(.*?);|

或查找前面的;或行开头:

|(;|^)from:(.*?);|m

将通用.*?匹配替换为[^;]*

于 2012-11-06T18:51:51.047 回答
1

我会给你解决方案,但我最好向你解释一下lookbehind修饰符。

例如,在正则表达式中,每次“匹配” ah时,h都会将 1 添加到正则表达式当前所在位置的指针,因此您不想向指针“添加”任何内容。您只想查看from前面是否有 a;\s\b或字符串的开头。您不想匹配 VOID,因为到处都有空隙!

所以,举个例子:(?<a)b这将匹配一个前面b有一个的a。所以它只是做下一个:当b找到它时,它会在它之前查找,如果有a它匹配正则表达式。

所以...会在它有之前(?<=[;\s\b]|^)from:(\w+\.\w+)匹配那个from[;\s\b] OR ^ (The string start)

演示

很简单吧!?

于 2012-11-06T19:00:17.480 回答
0

假设前面from是空格或;

/[\s\b;]from:([^;]+);/

这只会匹配from前面有空格、单词边界或;. 我也更喜欢缩小捕获范围,即[^;]+vs. [.*?];。

于 2012-11-06T18:51:19.203 回答
0

有一个概念叫做(否定)lookbehind,它断言你当前的位置是(不是)在某些事情之前。我想,在这种情况下,我会采用积极的后视方式,并断言from前面是字符串的开头、换行符或;

preg_match('|(?<=^|;)from:(.*?);|m', $string, $match);

确保您使用 multi-line mode m,这样它^也将在每行的开头匹配,而不仅仅是在字符串的开头。

如果您只想排除l_前面from但接受任何其他字符,那么负面的向后看可能是您正在寻找的:

preg_match('|(?<![l_])from:(.*?);|m', $string, $match);

后视的方便之处在于,它们不包含在实际匹配中。他们只是检查那里有什么而不​​实际消费它。这里有一些阅读。

于 2012-11-06T18:51:53.380 回答