如何匹配一个字母或者许多一个PHP使preg_split样式正则表达式

时间:2020-03-06 14:27:11  来源:igfitidea点击:

我有我的正则表达式的问题。

我想捕获<%一些东西%>,并且我需要<%和%>中的内容

这个正则表达式可以很好地工作。

$matches = preg_split("/<%[\s]*(.*?)[\s]*%>/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

我也想捕捉&%一些东西%>,所以我需要分别捕捉&lt;%或者&lt;%和%>或者%>

如果我放入第二组parens,它将使preg_split功能有所不同(因为正如我们从标志中看到的那样,我正在尝试捕获paren中的内容。

最好只匹配&lt;to>和&lt;to>,但这不是完全必要的

编辑:主题可能包含多个匹配项,而我需要所有这些匹配项

解决方案

在情况下,最好将preg_match及其添加参数和括号一起使用:

preg_match("#((?:<|&lt;)%)([\s]*(?:[^?]*)[\s]*?)(%(?:>|&gt;))#i",$markup, $out);
print_r($out);

Array
(
    [0] => <% your stuff %>
    [1] => <%
    [2] => your stuff
    [3] => %>
)

顺便说一句,检查此在线工具以调试PHP regexp,它非常有用!

http://regex.larsolavtorvik.com/

编辑:我砍死正则表达式了一点,所以它的速度更快。经过测试,它可以工作:-)

现在让我们解释所有这些东西:

  • preg_match将他捕获的所有内容存储在作为第三个参数传递的var中(此处为$ out)
  • 如果preg_match与某项匹配,它将存储在$ out [0]中
  • 任何在图形内(),而不是(?:)将存储在$出

详细内容:

#((?:<|&lt;)%)([\s]*(?:[^?]*)[\s]*?)(%(?:>|&gt;))#i can be viewed as ((?:<|&lt;)%) + ([\s]*(?:[^?]*)[\s]*?) + (%(?:>|&gt;)).

((?:<|&lt;)%) is capturing < or &lt; then %
(%(?:>|&gt;)) is capturing % then < or &gt; 
([\s]*(?:[^?]*)[\s]*?) means 0 or more spaces, then 0 or more times anything that is not the ? symbol, the 0 or more spaces.

为什么我们使用[^?]而不是。 ?这是因为 。这非常耗时,regexp引擎会在所有现有字符中进行检查。 [^?]只需检查字符是否不是?。没有人使用?,它是国际货币符号,但是如果我们愿意,可以将其替换为chr(7),这是显然不会在网页上键入的shell bell char。

EDIT2:我刚刚看了你的编辑有关捕获所有的比赛。在这种情况下,我们将以相同的方式使用preg_match_all。

一种可能的解决方案是像这样使用多余的括号,但要舍弃结果中的括号,因此我们实际上只使用了总数的1/2.

此正则表达式

$matches = preg_split("/(<|&lt;)%[\s]*(.*?)[\s]*%(>|&gt;)/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

用于输入

Hi my name is <h1>Issac</h1><% some stuff %>here&lt;% more stuff %&gt;

输出将是

Array(
 [0]=>Hi my name is <h1>Issac</h1>
 [1]=><
 [2]=>some stuff
 [3]=>>
 [4]=>here
 [5]=>&;lt;
 [6]=>more stuff
 [7]=>&gt;
)

如果我只使用偶数,这将给出所需的结果

如果我们真正想要的是括号内的匹配项,为什么要使用preg_split呢?似乎只使用preg_match会更简单。

正则表达式经常会出现问题,parens既用于对逻辑进行分组,又用于捕获模式。

根据有关正则表达式语法的PHP文档,

The fact that plain parentheses fulfil two functions is not always helpful. There are often times when a grouping subpattern is required without a capturing requirement. If an opening parenthesis is followed by "?:", the subpattern does not do any capturing, and is not counted when computing the number of any subsequent capturing subpatterns.

<?php
$code = 'Here is a <% test %> and &lt;% another test %&gt; for you';
preg_match_all('/(<|&lt;)%\s*(.*?)\s*%(>|&gt;)/', $code, $matches);
print_r($matches[2]);
?>

结果:

Array
(
    [0] => test
    [1] => another test
)

如果你想匹配,给preg_match_all一个镜头用正则表达式是这样的:

preg_match_all('/((\<\%)(\s)(.*?)(\s)(\%\>))/i', '<% wtf %> <% sadfdsafds %>', $result);

这导致几乎所有太阳下的比赛。我们可以添加/删除括号以匹配更多/更少:

Array
(
 [0] => Array
    (
        [0] => <% wtf %>
        [1] => <% sadfdsafds %>
    )

[1] => Array
    (
        [0] => <% wtf %>
        [1] => <% sadfdsafds %>
    )

[2] => Array
    (
        [0] => <%
        [1] => <%
    )

[3] => Array
    (
        [0] =>  
        [1] =>  
    )

[4] => Array
    (
        [0] => wtf
        [1] => sadfdsafds
    )

[5] => Array
    (
        [0] =>  
        [1] =>  
    )

[6] => Array
    (
        [0] => %>
        [1] => %>
    )

)