破折号

时间:2016-05-05 03:04:33

标签: regex

我在使用正则表达式时遇到了一些问题。 我正在测试机智案例1

\b(water|watering)\b/g

以上表达式可以匹配"浇水"成功。

但如果我在案例2之间加了一个连字符:

\b(water|water-ing)\b/g

它不能与水中的浇水相匹配"。
它只适用于我移动"浇水"表达到前面,如案例3:

\b(water-ing|water)\b/g

但我想知道案例编号2是否有任何解决方案,而不修改捕获组的顺序。

以下是参考:https://regex101.com/r/kR1bL0/2

4 个答案:

答案 0 :(得分:2)

你可以这样做:

\b(water-ing|water)\b/g

https://regex101.com/r/fC8wO1/1

因为“水”在“浇水”里面,你必须首先“浇水”,如果正则表达不能找到它,它会试图找到“水”。

或者你可以这样做:

\b(water(?:-ing)?)\b/g

使用“?:”来避免使用“()”创建另一个组非常重要。

https://regex101.com/r/yC8uM2/3

答案 1 :(得分:2)

关于轮替的注意事项

在交替中,在字符串中的当前位置检查每个替代项,直到其中一个交替成功或全部失败。

案例I

你的字符串是

water watering

你的正则表达式是

/\b(water|watering)\b/g

i)首先,检查第一次交替,如\bwater。它成功并且water匹配,因为water watering中的水后面有一个空格作为结束词边界。

ii)再次由于g标志,执行匹配。因此,正在尝试将字符串watering\bwater\b(以及最后的字边界)匹配,但它失败了,因为在iwater中有\bwatering这不是字边界。然后检查第二次交替,即\bwatering\b并且它成功,因为最后有一个字符串结尾作为water water-ing 的字边界。

案例II

你的字符串是

/\b(water|water-ing)\b/g

正则表达式

water water-ing
    ^^
    || 

i)与案例I的第I步相同

现在消耗了水,我们的检查位置是空白空间,然后浇水

g

ii)再次由于\bwater标志执行检查。首先使用-进行替换。该位置现在位于r之后i

之前water water-ing ^^ ||
-

引自 here 关于字边界

  

大多数正则表达式方言中的单词边界是\ w和。之间的位置   \ W(非单词char),或者如果是字符串的开头或结尾   用字符([0-9A-Za-z_])开始或结束(分别)。   破折号不是单词字符。

因此\bwater\b充当单词边界,water-ing

匹配/\b(water-ing|water)\b/g

enter image description here

案例III

正则表达式

\bwater-ing

i)首先在字符串中检查water,但它与字符串\bwater不匹配。再次,检查第二个替换water并且成功,因为字符串中\bwater-ing之后有一个空格。

ii)在存在的字符串中检查第一次交替water-ing。该字符串以此单词$结尾。所以字符串的结尾(\b(water(?!-)|water-ing)\b )充当单词边界。并且匹配成功。

enter image description here enter image description here

解决方案是什么?

i)如果正则表达式重叠,请保留最长的正则表达式,依此类推,就像在上一个解决方案中使用的一样

ii)你可以使用像

这样的负向前瞻
--r--r--r--o--o--o (src)
        |
   (origin/dst)

git push +src:dst

--r--r--r--o--o--o (src)
                 |
            (origin/dst)

似乎Wiktor已经提出了四种解决方案。你可以使用其中任何一个

答案 2 :(得分:0)

不同的正则表达式引擎为“单词边界”定义不同的字符集。例如,ECMAScript specifies a word character as one of 63 characters-未列在那里。因此-被视为ECMAScript中的单词边界。

显然,\b不适合Unicode字。所以你应该使用你自己的一组字符,这些字符应该是字边界。

例如,在PHP中,您可以使用以下内容:

preg_match_all('/[\p{L}\-]+/u', 'water water-ing', $m);
var_dump($m);
/*
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "water"
    [1]=>
    string(9) "water-ing"
  }
}
*/

其中\p{L}代表Unicode "letter" category。见PHP Unicode character properties

答案 3 :(得分:0)

你可以用这个: \b(water(ing)?)\g