如何匹配一个字母或者许多一个PHP使preg_split样式正则表达式
我有我的正则表达式的问题。
我想捕获<%一些东西%>,并且我需要<%和%>中的内容
这个正则表达式可以很好地工作。
$matches = preg_split("/<%[\s]*(.*?)[\s]*%>/i",$markup,-1,(PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));
我也想捕捉&%一些东西%>
,所以我需要分别捕捉<%或者<%和%>或者%>
。
如果我放入第二组parens,它将使preg_split功能有所不同(因为正如我们从标志中看到的那样,我正在尝试捕获paren中的内容。
最好只匹配<to>和<to>
,但这不是完全必要的
编辑:主题可能包含多个匹配项,而我需要所有这些匹配项
解决方案
在情况下,最好将preg_match及其添加参数和括号一起使用:
preg_match("#((?:<|<)%)([\s]*(?:[^?]*)[\s]*?)(%(?:>|>))#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]中
- 任何在图形内(),而不是(?:)将存储在$出
详细内容:
#((?:<|<)%)([\s]*(?:[^?]*)[\s]*?)(%(?:>|>))#i can be viewed as ((?:<|<)%) + ([\s]*(?:[^?]*)[\s]*?) + (%(?:>|>)). ((?:<|<)%) is capturing < or < then % (%(?:>|>)) is capturing % then < or > ([\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("/(<|<)%[\s]*(.*?)[\s]*%(>|>)/i",$markup,-1,(PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));
用于输入
Hi my name is <h1>Issac</h1><% some stuff %>here<% more stuff %>
输出将是
Array( [0]=>Hi my name is <h1>Issac</h1> [1]=>< [2]=>some stuff [3]=>> [4]=>here [5]=>&;lt; [6]=>more stuff [7]=>> )
如果我只使用偶数,这将给出所需的结果
如果我们真正想要的是括号内的匹配项,为什么要使用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 <% another test %> for you'; preg_match_all('/(<|<)%\s*(.*?)\s*%(>|>)/', $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] => %> ) )