Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如果第一个X中有一个X,第二个Y可以是0,则匹配_Regex - Fatal编程技术网

Regex 如果第一个X中有一个X,第二个Y可以是0,则匹配

Regex 如果第一个X中有一个X,第二个Y可以是0,则匹配,regex,Regex,我目前正在做一个项目。我需要一个正则表达式,它取Y和X,并且X对之间用Y分隔。它不必是相等的数字,但不能包含多个X'e 示例: # Don't match: XXXYYYYY #Match: XYXYYYY X 我迄今为止的努力: {Y*[X |^X]Y*[X |^X]Y*}* 问题是,如果第一个和第二个分别有X和X,Y仍然可以是0。我可以直接测试双X吗 它有什么不寻常之处 ^(?:X(?!X)|Y)+$ 说明:这只是一系列的X和Y,其中一个X后面不能跟另一个X(负向前看)。它有什么不寻

我目前正在做一个项目。我需要一个正则表达式,它取Y和X,并且X对之间用Y分隔。它不必是相等的数字,但不能包含多个X'e

示例:

# Don't match:
XXXYYYYY
#Match:
XYXYYYY
X
我迄今为止的努力:

{Y*[X |^X]Y*[X |^X]Y*}*
问题是,如果第一个和第二个分别有X和X,Y仍然可以是0。我可以直接测试双X吗

它有什么不寻常之处

^(?:X(?!X)|Y)+$

说明:这只是一系列的X和Y,其中一个X后面不能跟另一个X(负向前看)。

它有什么不寻常之处

^(?:X(?!X)|Y)+$

说明:这只是一系列的X和Y,其中一个X不能后跟另一个X(负前瞻)

试试这个。这应该可以满足您的要求。请参阅演示

试试这个。这应该可以满足您的要求。请参阅演示


您可以使用此模式:

^Y*(XY+)*X?$
如果要确保至少有一个字符,可以单独检查长度或在开头添加前瞻:

^(?=.)Y*(?:XY+)*X?$
关于灾难性回溯:

如果使用DFA正则表达式引擎,则不会出现问题,因为没有回溯

如果使用NFA正则表达式引擎,可以通过以下几种方法防止灾难性回溯:

^Y*(XY|Y)*X?$       # possible but not really efficient

^Y*(?>XY+)*X?$      # using an atomic group (if available)

^Y*(?:XY+)*+X?$     # using a possessive quantifier (if available)

^Y*(?=((XY+)*))\1X?$ # emulate `(?>(?:XY+)*)`

^Y*(?:(?=(XY+))\1)*X?$  # emulate `(?>XY+)*`

您可以使用以下模式:

^Y*(XY+)*X?$
如果要确保至少有一个字符,可以单独检查长度或在开头添加前瞻:

^(?=.)Y*(?:XY+)*X?$
关于灾难性回溯:

如果使用DFA正则表达式引擎,则不会出现问题,因为没有回溯

如果使用NFA正则表达式引擎,可以通过以下几种方法防止灾难性回溯:

^Y*(XY|Y)*X?$       # possible but not really efficient

^Y*(?>XY+)*X?$      # using an atomic group (if available)

^Y*(?:XY+)*+X?$     # using a possessive quantifier (if available)

^Y*(?=((XY+)*))\1X?$ # emulate `(?>(?:XY+)*)`

^Y*(?:(?=(XY+))\1)*X?$  # emulate `(?>XY+)*`

因为上面的答案使用了前瞻性,所以这个答案提供了一个普通正则表达式的解决方案:

^(X?Y)*X?$
上述解决方案假定允许使用空字符串。否则:

^((X?Y)+X?|X)$
(请随意将组设置为非捕获)

多亏了单面体的简化
XY | Y
X?Y


如果还有人对这个答案的正确性有疑问:

DFA可从上述方程式中得出


如果不允许使用空字符串,请删除
R1
中的

由于上述答案使用了前瞻性,此答案提供了一个普通正则表达式的解决方案:

^(X?Y)*X?$
上述解决方案假定允许使用空字符串。否则:

^((X?Y)+X?|X)$
(请随意将组设置为非捕获)

多亏了单面体的简化
XY | Y
X?Y


如果还有人对这个答案的正确性有疑问:

DFA可从上述方程式中得出



如果不允许使用空字符串,请删除
R1
中的

@almasshaikh已经更新了问题:为什么不直接测试
XX
,发现时拒绝?@单面体不是重点,请您对此作出反应,抱歉,但我需要的只是一些理论,也许我可以测试双X或类似的东西你在找什么样的RE?style regex,或style ERE,或@almasshaikh重复使用的平原更新了问题:为什么不直接测试
XX
并在发现时拒绝?@单面体这不是重点,请您对此作出反应,抱歉,但我需要的只是一些理论,也许我可以测试双X或类似的东西你在找什么样的RE?由于
Y
在逻辑上看起来等于或大于
X
s的数量,因此将替换项更改为在前面包含
Y
,可能会使其在匹配输入时稍微更有效。@Unihedron您甚至可以做得更好:
^(?:Y++|X(?!X))+$
^(?:(?>Y+)| X(?!X))+$
但由于OP没有指定正则表达式的风格,我省略了优化。有见地的评论和很棒的观点!然而值得注意的是,在PCRE中,
Y++
被定义为与
(?>Y+
)相同。是的,但例如,所有格量词修饰符(
++
)在.NET中不可用,因此您必须使用原子组(
(?>)
)。。。同样,一切都取决于味道:)因为
Y
在逻辑上看起来等于或大于
X
s的数量,所以将替换项更改为在前面包含
Y
,可能会使其在匹配输入时稍微更有效。@Unihedron您甚至可以做得更好:
^(?:Y++;X(?!X))++$
^((?>Y+)|X(?!X))+$
但是由于OP没有指定正则表达式的风格,我没有进行优化。有见地的评论和很棒的观点!然而值得注意的是,在PCRE中,
Y++
被定义为与
(?>Y+
)相同。是的,但例如,所有格量词修饰符(
++
)在.NET中不可用,因此您必须使用原子组(
(?>)
)。。。同样,一切都取决于味道:)有趣的理论,尽管为了避免灾难性的回溯烧掉用户的代码,最好使用
(?>)
而不是
(?:)
语言支持的:)
^Y*(XY | Y)*X?$
删除第一个
Y*
(因为
(XY | Y)*
已经包含在
(XY | Y)*
中,解决方案将与我的相同。其余部分是多余的,因为
^(XY | Y)*X?$
永远不会有回溯问题。@nhahdh:
^Y*(XY | Y)*X?$
确实可以缩短为
^(X?Y)*X?$
。但是,此模式的效率较低,因为失败前的步数比使用原子分组的模式大4倍。因此,它们一点都不冗余。因此,通过单面体简化,最有效的模式是
^(?>X?Y+)*+X?$
@casimirithippolyte:我无法观察到4x的差异。但是,如果我使用
^(X?Y)*+X?$
,我确实看到了2x的差异。
(?>
在可能的情况下是不必要的