Regex 带破折号的正则表达式问题
我对正则表达式有一些问题。 我正在测试案例1Regex 带破折号的正则表达式问题,regex,Regex,我对正则表达式有一些问题。 我正在测试案例1 \b(water|watering)\b/g 以上表达式可以成功匹配“water watering” 但是如果我在案例2的中间添加了一个连字符: \b(water|water-ing)\b/g 它无法与“water-water-ing”中的“water-water-ing”匹配 仅当我将“water-ing”表达式移到前面时,它才起作用,如案例3所示: \b(water-ing|water)\b/g 但我想知道,在不改变捕获组顺序的情况下,是否
\b(water|watering)\b/g
以上表达式可以成功匹配“water watering”
但是如果我在案例2的中间添加了一个连字符:
\b(water|water-ing)\b/g
它无法与“water-water-ing”中的“water-water-ing”匹配仅当我将“water-ing”表达式移到前面时,它才起作用,如案例3所示:
\b(water-ing|water)\b/g
但我想知道,在不改变捕获组顺序的情况下,是否有任何解决方案
以下是参考资料:您可以这样做:
\b(water-ing|water)\b/g
\b(water(?:-ing)?)\b/g
因为“water”在“water-ing”中,你必须把“water-ing”放在第一位,如果正则表达式找不到它,它就会尝试找到“water”
或者您可以这样做:
\b(water-ing|water)\b/g
\b(water(?:-ing)?)\b/g
必须使用“?:”以避免创建另一个带有“()”的组
不同的正则表达式引擎为“单词边界”定义不同的字符集。例如,
-
未在此处列出。因此,-
在ECMAScript中被视为单词边界
显然,\b
不适合Unicode单词。所以你应该使用你自己的一组字符,它们应该是单词的边界
例如,在PHP中,您可以使用以下内容:
preg_match_all('/[\p{L}-]+/u','water-water-ing',$m);
var_dump(百万美元);
/*
阵列(1){
[0]=>
阵列(2){
[0]=>
串(5)“水”
[1]=>
第(9)串“注水”
}
}
*/
其中,\p{L}
代表一个。请参见您可以使用:
\b(水)水?)\g
关于交替的注意事项
在替换中,在字符串中的当前位置检查每个替换,直到其中一个替换成功或全部失败
案例一
你的绳子是
water watering
water water-ing
你的正则表达式是
/\b(water|watering)\b/g
i) 首先,像\bwater
一样检查第一次交替。它成功并匹配了water
,因为water watering
中的water之后有一个空格作为结束词边界
ii)由于g
标志,再次执行匹配。因此,字符串watering
正在尝试与\bwater\b
(以及结尾的单词边界)匹配,但它失败了,因为water
之后watering中存在i
,这不是单词边界。然后检查第二个替换,即\bwatering
,它成功了,因为在最后一个替换中,字符串的末尾充当\bwatering\b
的单词边界
案例二
你的绳子是
water watering
water water-ing
正则表达式
/\b(water|water-ing)\b/g
/\b(water-ing|water)\b/g
i) 与案例一的步骤一相同
现在绳子到水被消耗了,我们的检查位置是浇水前的空白
water water-ing
^^
||
ii)由于g
标志再次执行检查。使用\b水
尝试第一次交替。现在的位置是-
就在r
之后和i
之前
water water-ing
^^
||
引用关于单词边界
在大多数regex方言中,单词边界位于\w和\n之间
\W(非单词字符),或在字符串的开头或结尾,如果
分别以单词字符([0-9A-Za-z_])开始或结束。
破折号不是单词字符
因此,-
充当单词边界,\bwater\b
在water-ing
案例三
正则表达式
/\b(water|water-ing)\b/g
/\b(water-ing|water)\b/g
i) 在字符串中选中了第一个替换项\b水
,但它与字符串水
不匹配。再次检查第二次交替\bwater
,它成功了,因为字符串中water
后面有一个空格
ii)在出现的字符串中检查第一次交替\b注水。字符串以单词water-ing
结尾。所以字符串的结尾($
)充当单词边界。比赛成功了
解决方案是什么?
i) 如果存在重叠的正则表达式,请在开始时保留最长的正则表达式,依此类推,就像在上一个解决方案中使用的一样
ii)您可以使用负前瞻,如
\b(water(?!-)|water-ing)\b
它似乎已经提出了四个解决方案。您可以使用它们中的任何一个发生这种情况是因为中的-
和单词边界\b
。如果不重新排序或更改第一个分支模式,您将无法实现您想要的目标。我的意思是:1)或,或2)。