Php 用于匹配序列的正则表达式?
我的文本包含已知模式中的短语,例如:Php 用于匹配序列的正则表达式?,php,regex,pcre,Php,Regex,Pcre,我的文本包含已知模式中的短语,例如:。%some phrase%,该短语可以是任何内容(显然,它不包括模式'%.')。 现在,我想构建一个正则表达式(在php中),它将匹配2个或更多短语的序列(它们之间有或没有空格),例如,如果我的文本是: #%jjj jjj%# kkjjkkjj kkjjkkjj #%kkk kkk%# #%ttt mmm%# 我希望正则表达式匹配: #%kkk kkk%# #%ttt mmm%# 我试过这个正则表达式:/(?:#%。+?(?!%#).%#\s*){2
。%some phrase%
,该短语可以是任何内容(显然,它不包括模式'%.'
)。现在,我想构建一个正则表达式(在php中),它将匹配2个或更多短语的序列(它们之间有或没有空格),例如,如果我的文本是:
#%jjj jjj%# kkjjkkjj kkjjkkjj #%kkk kkk%# #%ttt mmm%#
我希望正则表达式匹配:
#%kkk kkk%# #%ttt mmm%#
我试过这个正则表达式:/(?:#%。+?(?!%#).%#\s*){2,}/
但出于某种奇怪的原因,它匹配整个字符串,并忽略了负的前瞻
此外,我的全部任务是匹配一系列短语,它们之间最多有一个字符(除了空格)
如何实施
测试用例:
正文:
#%主要目标%##################################关于我们%#
应匹配:
根据您的测试输入,我提出了这个正则表达式,它简短而有效
/((?:#%[^#]*%#(?:\s.\s|\s)){2,})/g
测试字符串
测试1
\%Prime target%\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>
测试2
#%Prime target%#英式德语-挪威斯文斯卡-索米英语-非英语CA#%Home%#关于我们%#公平竞争%#促销%#
结果
- 比赛1
- [8-42]
#%Prime target%##%Online stuff%#
- 比赛2
- [100-151]
#%Home%###%About Us%###%Fair Play%##%Promotions%#
- 比赛3
- [236-293]
#%Home%#|##%About Us%#|##%Fair Play%#|##%Promotions%#
尝试演示我想您需要:
/(?:.*?#%.*?%#.*?)(#%.*%#)/g
它首先查找%..%
(ungreedy),然后匹配下一个%..%
(贪婪)
您必须修改正则表达式:
(?:#%(?:(?!%#).)+?.%#\s*)(?:.?\s*#%(?:(?!%#).)+?.%#\s*)+
在(?:)
组的lookback中包装+?
捕获将强制惰性匹配在继续时不匹配(?!%#)
,这也是原始正则表达式无法工作的原因
另外,将其克隆到具有匹配前缀?
的单独组中,以便组之间可以接受字符
这里有一个
测试用例:
#%jjjjj%#kkjjkjjjkjjjkjjj%#%kkkkk%#%ttt mmm%#
匹配:
#%kkk kkk%#%ttt mmm%#
但它也匹配短语之间的任何内容,我只想匹配一个短语序列,如解释的,它们之间最多有一个字符和空格。@pushpraj我想你不明白我的意思,我不想匹配每个短语,我想匹配整个序列(如果它包含两个以上的短语,带或不带空格,并且可选地在它们之间包含一个字符),在这种情况下,只需将其修改为/(?这似乎有效!我将不得不用更复杂的文本来测试它,以确保…你能再次向我解释一下为什么这次修改会有不同吗?我没有使用向后看,而是使用负向前看,(?:)只是一个非捕获组。问题是:中的(?:#%。+?!%#%。%#s*){2,}
,您的查找实际上是无用的。+?
告诉引擎一个字符接一个字符,直到它可以到达下一个序列-(?!%#).
这意味着只要字符串的一部分以%
开头,另一部分以%
开头,您的旧正则表达式就会从字符串中的第一个到最后一个%
匹配。这意味着,一切。我的解决方法是强制执行(?!%\
关于+?
匹配。我写道“我的全部任务是匹配一系列短语,它们之间最多有一个字符(除了空格)。”我根据您的测试输入更新了我的答案,看看这是否有用