代码之家  ›  专栏  ›  技术社区  ›  Clayton

如何匹配PHP preg_split样式正则表达式中的一个或多个字母

  •  2
  • Clayton  · 技术社区  · 16 年前

    我的正则表达式有问题。

    我想捕获<%一些东西%>我需要的是<%以及%>

    这个正则表达式对此非常有效。

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

    我还想抓住你 &amp;% some stuff %&amp;gt; 所以我需要捕捉 <% or &amp;lt;% and %> or %&amp;gt;

    如果我放入第二组paren,它会使preg_split函数不同(因为从标志中可以看到,我试图捕获paren中的内容)。

    &amp;lt; to &amp;gt; and < to > 当然,但这不是完全必要的

    5 回复  |  直到 10 年前
        1
  •  9
  •   Bite code    16 年前

    preg_match("#((?:<|&lt;)%)([\s]*(?:[^ø]*)[\s]*?)(%(?:>|&gt;))#i",$markup, $out);
    print_r($out);
    
    Array
    (
        [0] => <% your stuff %>
        [1] => <%
        [2] => your stuff
        [3] => %>
    )
    

    http://regex.larsolavtorvik.com/

    编辑:我对regexp进行了一些黑客攻击,所以速度更快。测试它,它工作:-)

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

    • preg_match将存储他在作为第三个参数传递的var中捕获的所有内容(此处为$out)

    具体模式如下:

    #((?:<|&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字符,显然永远不会在网页中键入。

        2
  •  2
  •   Lasar    16 年前
    <?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
    )
    
        3
  •  1
  •   Tegan Mulholland    16 年前

    你为什么用这个 preg_split 如果您真正想要的是括号内的匹配项?似乎只使用它会更简单 preg_match

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

    普通括号实现两个功能的事实并不总是有用的。有时需要分组子模式而不需要捕获。如果左括号后接“?:”,则子模式不执行任何捕获,并且在计算任何后续捕获子模式的数量时不进行计数。

        4
  •  1
  •   A J    9 年前

    如果你想比赛,就给我 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] => %>
        )
    
    )
    
        5
  •  0
  •   Clayton    16 年前

    一个可能的解决方案是使用额外的参数,就像这样,但要在结果中去掉这些参数,所以实际上只需要 使用

    这个正则表达式

    $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;
    )
    

    如果我只使用偶数,那会得到想要的结果