我仔细地寻找过以前问过这个问题的问题;唉,我对PHP preg_match
搜索的搜索没有返回任何结果(也许我的搜索技能不足,我想考虑到这是一个正则表达式问题!(。
请考虑以下文本:
狐狸
__("brown ")
跳跃__('over the')
懒惰的__("dog")
现在目前我需要"扫描"上面__('')
给定的方法,而它可以包括间距和不同的引号( '
|"
(。经过多次"迭代"后,我最好的尝试:
(__'("(.*?)"'))|(__'('(.*?)''))
或者最简单的形式:
__'((.*?)')
要分解一下:
- 任何以
__
开头的东西 - 转义
(
和引号"
或'
。因此,'('"
-
(.*?)
所有角色的非贪婪匹配 - 转义了右
"
和最后一个括号。 - 两个表达式之间的
|
匹配 要么/要么。
但是,这只会获得部分匹配,并且空格完全抛弃了搜索。抱歉,如果之前有人问过这个问题,如果是这样,请链接我!
上面提供的模式的测试器链接:
PHP 实时正则表达式测试工具
当搜索的方法字符串使用单引号时,它最终将出现在另一个捕获组中,而不是具有双引号。所以事实上,你的正则表达式是有效的(除了空格,见下文(,但你必须在结果数组中查看不同的索引:
$input = 'The quick __("brown ") fox jumps __(''over the'') lazy __("dog")';
// using your regular expression:
$res = preg_match_all("/(__'('"(.*?)'"'))|(__'('(.*?)''))/", $input, $matches);
print_r ($matches);
请注意,您需要preg_match_all
而不是preg_match
才能获得所有匹配项。
输出:
Array
(
[0] => Array
(
[0] => __("brown ")
[1] => __('over the')
[2] => __("dog")
)
[1] => Array
(
[0] => __("brown ")
[1] =>
[2] => __("dog")
)
[2] => Array
(
[0] => brown
[1] =>
[2] => dog
)
[3] => Array
(
[0] =>
[1] => __('over the')
[2] =>
)
[4] => Array
(
[0] =>
[1] => over the
[2] =>
)
)
因此,结果数组有 5 个元素,第一个元素表示完全匹配,所有其他元素对应于正则表达式中的 4 个捕获组。由于单引号的捕获组不是双引号的捕获组,因此您会在不同位置找到匹配项。
为了"解决">这个问题,你可以在正则表达式中使用反向引用,它会回头看看哪个是开场引号(单引号或双引号(,并要求在末尾重复相同的引号:
$res = preg_match_all("/__'((['"'])(.*?)''1')/", $input, $matches);
请注意反向引用'1
(反斜杠必须使用另一个反斜杠进行转义(。这又回到了第一个捕获组,其中我们有["']
(再次需要转义(来匹配这两种引号。
您还想处理空间。在你的PHP Live Regex上,你使用了一个测试字符串,在括号和引号之间有这样的空格。为了处理这些问题,使它们仍然正确匹配方法字符串,正则表达式应该得到两个额外的's*
:
$res = preg_match_all("/__'('s*(['"'])(.*?)''1's*')/", $input, $matches);
现在输出为:
Array
(
[0] => Array
(
[0] => __("brown ")
[1] => __('over the')
[2] => __("dog")
)
[1] => Array
(
[0] => "
[1] => '
[2] => "
)
[2] => Array
(
[0] => brown
[1] => over the
[2] => dog
)
)
。小组捕获的文本现在排列得很好。
请参阅在 eval.in 和 PHP Live Regex 上运行的此代码。
在处理这样的东西时,不要忘记转义:
<?php
ob_start();
?>
The quick __("brown ") fox jumps __( 'over the' ) lazy __("dog").
And __("everyone says '"hi'"").
<?php
$content = ob_get_clean();
$re = <<<RE
/__ '(
's*
" ( (?: ''''. | [^"])+ ) "
|
' ( (?: ''''. | [^'])+ ) '
's*
')
/x
RE;
preg_match_all($re, $content, $matches, PREG_SET_ORDER);
foreach($matches as $match)
echo end($match), "'n";
这个怎么样:
(__('('[^']+'')|'("[^"]+"')))
代替非贪婪的.
,使用除引号[^']
或[^"]
以外的任何字符
用方括号将双引号和单引号括起来作为字符类:
$str = 'The quick __( "brown ") fox jumps __(''over the'') lazy __("dog")';
preg_match_all("/__'('s*(['"']).*?''1's*')/ium", $str, $matches);
echo '<pre>';
var_dump($matches[0]);
// the output:
array (size=3)
0 => string '__( "brown ")'
1 => string '__('over the')'
2 => string '__("dog")'
这是在 phpliveregex.com 上使用相同的解决方案的示例:
http://www.phpliveregex.com/p/exF(第preg_match_all
节(