如何匹配所有单词,但"停止"在正则表达式的字符串中

时间:2016-01-10 12:50:33

标签: php regex string

另一个正则表达式问题。我使用PHP,并有一个字符串:fdjkaljfdlstopfjdslafdj。你看到中间有一个stop。我只想替换除stop之外的任何其他单词。我尝试使用[^stop],但它还包含字符串末尾的s



我的解决方案

感谢大家的帮助。

我也找到了一个纯RegEx方法的解决方案(我的意思是我对RegEx的知识独家报道.PCRE动词对我来说太先进了)。但它需要两个步骤。我不想混合使用PHP方法,因为有时作业不在编码区域,即Total Commander中的多重命名文件名。

让我们看一下字符串:xxxfooeoropwfoo,skfhlk;afoofsjre,jhgfs,vnhufoolsjunegpq。例如,我希望将所有foo保留在此字符​​串中,并将任何其他non-foo贪婪地替换为---

首先,我需要找到每个foo之间的所有非foo:(?<=foo).+?(?=foo)。 该字符串将变为xxxfoo---foo---foo---foolsjunegpq,现在只剩下双方non-foo字了。

然后使用[^-]+(?=foo)|(?<=foo)[^-]+。 这一次:---foo---foo---foo---foo---。除foo之外的所有字词都已转换为---

3 个答案:

答案 0 :(得分:1)

  

我只是不想包括&#34;停止&#34; ...

您可以使用PCRE verbs (*SKIP)(*F)试试这个

来跳过它
stop(*SKIP)(*F)|.

Demo at regex101

或序列:(stop)(*SKIP)(*F)|(?:(?!(?1)).)+

或单词:stop(*SKIP)(*F)|\w+

答案 1 :(得分:0)

[^stop]并不代表任何非stop的文字。它只表示[...]中{4}中不是4个字符之一的任何字符,在这种情况下s,t,o,p

最好分割你不想匹配的文字:

$s = 'fdjkaljfdlstopfjdslafdjstopfoobar';

php> $arr = preg_split('/stop/', $s);

php> print_r($arr);
Array
(
    [0] => fdjkaljfdl
    [1] => fjdslafdj
    [2] => foobar
)

答案 2 :(得分:0)

您可以将此概括为任何模式:

(?<neg>stop)(*SKIP)(*FAIL)|(?s:.)+?(?=\Z|(?&neg))

Demo

只需将您不想要的模式放在neg组中。

此正则表达式将尝试对任何字符位置执行以下操作:

  • 匹配您不想要的模式。如果匹配,请将其丢弃(*SKIP)(*FAIL)并在此位置重新开始另一场比赛。
  • 如果您不想要的模式在特定位置不匹配,则匹配任何内容,直到:
    • 您到达输入字符串的末尾(\Z
    • 或者您不想要的模式紧跟当前匹配位置((?&neg)

这种方法比手动调整表达式慢,你可以以重复自己为代价获得更好的性能,避免了递归:

stop(*SKIP)(*FAIL)|(?s:.)+?(?=\Z|stop)

当然,最好的方法是使用您的语言提供的功能:匹配您想要的字符串,然后使用代码丢弃它并保留其他所有内容。

在PHP中,您可以使用PREG_OFFSET_CAPTURE标志告诉preg_match_all函数为您提供每场比赛的偏移量。