我问过一个类似的问题,但因为太宽泛而被关闭了。基本上,我有一堆这样的问题。我希望只问一个会更容易。我尝试了一些不同的方法来解决这个问题,但没有一个真正有效。
我有一个包含大量数据的文本文件。我唯一感兴趣的数据位于两个括号"(")"之间。我想知道如何获得位于括号之间的信息的每个实例到一个数组。
我现在使用的代码返回ArrayArray
:
function get_between($startString, $endString, $myFile){
preg_match_all('/$startString([^$endString]+)}/', $myFile, $matches);
return $matches;
}
$myFile = file_get_contents('explode.txt');
$list = get_between(" (", ")", $myFile);
foreach($list as $list){
echo $list;
}
你的正则表达式完全被误导了。
第一:[^...]
是一个互补字符类。一个互补的字符类是一个原子,无论...
是什么,它都是一组此时必须不允许的字符。例如,[^ab]
将允许除a
和b
之外的任何内容。
第二:你似乎想要能够捕捉父母之间。但是父字符(打开或关闭)是正则表达式中的一个特殊字符。因此,在您的示例中,如果$startString
是 (
,则父级将被解释为regex元字符。
第三:不幸的是,这不能用正则表达式解决,但是嵌套的$startString
和$endString
不能匹配(好吧,它们可以用perl,但perl是perl)。
最接近你真正想要的是重写你的正则表达式使用preg_match_all
,如下所示:
$start = preg_quote($startString, '/');
$end = preg_quote($endString, '/');
$re = '/Q' . $start . 'E' # literal $start
. '(' # capture...
. '(?:(?!Q' . $end . 'E).)' # any character, as long as $end is not found at this position,
. '+)' # one or more times
. 'Q' . $end . 'E/'; # literal $end
,然后使用它作为preg_match_all
的第一个参数。
Q
和E
正则表达式修饰符告诉我们,第一个和第二个之间的任何内容都应该被视为字面量——因此 (
中的父字符将被视为字面量,而不是作为组开头的元字符。
<?php
function get_between($startString, $endString, $myFile){
//Escape start and end strings.
$startStringSafe = preg_quote($startString, '/');
$endStringSafe = preg_quote($endString, '/');
//non-greedy match any character between start and end strings.
//s modifier should make it also match newlines.
preg_match_all("/$startStringSafe(.*?)$endStringSafe/s", $myFile, $matches);
return $matches;
}
$myFile = 'fkdhkvdf(mat(((ch1)vdsf b(match2) dhdughfdgs (match3)';
$list = get_between("(", ")", $myFile);
foreach($list[1] as $list){
echo $list."n";
}
我这样做了,它似乎工作。(显然,您需要用file_get_contents语句替换我的$myFile赋值行。)几件事:
A:单引号不能替换变量。因此,您的preg_replace_all正则表达式将无法工作。因为它实际上是将$startString添加到表达式中,而不是(。(我还删除了在匹配字符串末尾对}的检查。如果需要的话,在结束分隔符之前使用\}
将其添加回来。)
B: $list将是一个数组的数组。我相信默认情况下,索引0将包含所有完整匹配。索引1将包含第一个子模式匹配。
C:这只在$endString不会在你试图匹配的子模式中找到的情况下才有效。比如说,如果你期望(match (fF))得到match (fF),它不会。它会给你匹配的(fF)。如果您希望在本例中得到前一种结果,则需要更强大的解析器。
编辑:这里的get_between函数应该与 (
和)}
一起工作,或者任何你想要的。