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

时间:2008-09-19 18:18:14

标签: php regex

我的正则表达式存在问题。

我想捕获<%some stuff%>我需要<%和%>

中的内容

这个正则表达式适用于此。

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

如果我放入第二组parens,它会使preg_split功能不同(因为从旗帜中可以看出,我正试图捕捉到parens中的内容。

最好,它只匹配&amp;lt; to &amp;gt; and < to >,但这不是完全必要的

编辑:SUBJECT可能包含多个匹配,我需要所有匹配

5 个答案:

答案 0 :(得分:9)

在您的情况下,最好使用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]
  • 模式中的任何内容()但不是(?:)将存储在$ 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.

为什么我们使用[^ø]代替。 ?这是因为 。非常耗时,正则表达式引擎将检查所有现有字符。 [^ø]只检查焦炭是否不是ø。没有人使用ø,它是一个国际货币符号,但是如果你关心,你可以用chr(7)取代它,它显然是永远不会在网页上输入的贝壳铃铛。

EDIT2:我刚刚阅读了关于捕捉所有比赛的编辑。在这种情况下,您将以相同的方式使用preg_match_all。

答案 1 :(得分:2)

<?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
)

答案 2 :(得分:1)

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

正则表达式经常出现问题,即parens用于分组逻辑和捕获模式。

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

  

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

答案 3 :(得分:1)

如果你想匹配,请给preg_match_all一个带 正则表达式 的镜头,如下所示:

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

这导致了太阳下几乎所有东西的匹配。您可以添加/删除parens以匹配更多/更少:

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] => %>
    )

)

答案 4 :(得分:0)

一种可能的解决方案是使用额外的parens,就像这样,但是在结果中抛弃那些,所以实际上只有使用总恢复的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;
)

如果我只使用偶数

,那将给出所需的结果