Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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
Php 用于匹配序列的正则表达式?_Php_Regex_Pcre - Fatal编程技术网

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,}/

但出于某种奇怪的原因,它匹配整个字符串,并忽略了负的前瞻

此外,我的全部任务是匹配一系列短语,它们之间最多有一个字符(除了空格)

如何实施

测试用例:

正文:

#%主要目标%##################################关于我们%#

应匹配:

  • #%主要目标%##%#
  • #%主场%###关于我们%###公平竞争%###促销%#
  • 正文:

    #%主要目标%#英国-德国-挪威斯文斯卡-索米英语-非英语CA%#家庭%#家庭%#关于我们%#公平竞争%#促销%#

    应匹配:

  • #%主场%#|##关于我们%#|##公平竞争%#|#促销%#

  • 根据您的测试输入,我提出了这个正则表达式,它简短而有效

    /((?:#%[^#]*%#(?:\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,}
    ,您的查找实际上是无用的。
    +?
    告诉引擎一个字符接一个字符,直到它可以到达下一个序列-
    (?!%#).
    这意味着只要字符串的一部分以
    %
    开头,另一部分以
    %
    开头,您的旧正则表达式就会从字符串中的第一个到最后一个
    %
    匹配。这意味着,一切。我的解决方法是强制执行
    (?!%\
    关于
    +?
    匹配。我写道“我的全部任务是匹配一系列短语,它们之间最多有一个字符(除了空格)。”我根据您的测试输入更新了我的答案,看看这是否有用