我有一个带有以下“有效”模式的字符串,该字符串会重复多次: 一组特定的字符,例如“ ab”,任意数量的其他字符,例如“ xx”,另一组特定的字符,例如“ cd”,任意数量的其他字符,例如“ xx”。
因此,有效序列为: “ abxcdabxxcdabxcdxx”
我正在尝试检测以下特定格式的无效序列:“ abxxcdxxcd”,并删除中间的“ cd”以使其有效:“ abxxxxcd”
我尝试了以下正则表达式:
/(?<=ab).*(cd).*(?=ab)/gsU
它适用于单个序列,但不适用于以下字符串: “ abxx cd xcdxxabxcdxxabx cd xxcd”,其中包含无效序列,后跟有效序列,然后是另一个无效序列。我想用粗体捕获两个组。
请注意,其他字符“ xx”可能包含任何内容,包括换行符。但是,除非我指定了无效的情况,否则它们绝不会包含字符串“ ab”或“ cd”。
以下是相应的regex101链接:https://regex101.com/r/U9pRfo/1
编辑:
Wiktor's answer为我效劳。但是,当在非常大的字符串上使用该正则表达式时,我在php中得到了PREG_JIT_STACKLIMIT_ERROR。我最后只是将字符串分成较小的块,然后重建字符串,效果很好。
答案 0 :(得分:1)
您可以使用
'~(?:\G(?!^)|ab)(?:(?!ab).)*?\Kcd(?=(?:(?!ab).)*?cd)~s'
请参见regex demo
(?:\G(?!^)|ab)
-匹配ab
或上一个匹配项结尾的捕捉组(?:(?!ab).)*?
-匹配任何不开始ab
字符序列的char,最多0次或更多次\K
-匹配重置运算符cd
-子字符串(?=(?:(?!ab).)*?cd)
-一个正向先行,它需要任何char,0个或多个重复(尽可能少的重复),并且不会开始ab
char序列,然后再开始cd
char序列。 / li>