递归正则与乱码文本周围?获得“ArrayArray"


Recursive regex with garbled text surrounding? Getting "ArrayArray"

我问过一个类似的问题,但因为太宽泛而被关闭了。基本上,我有一堆这样的问题。我希望只问一个会更容易。我尝试了一些不同的方法来解决这个问题,但没有一个真正有效。

我有一个包含大量数据的文本文件。我唯一感兴趣的数据位于两个括号"(")"之间。我想知道如何获得位于括号之间的信息的每个实例到一个数组。

我现在使用的代码返回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("&nbsp(", ")", $myFile);
foreach($list as $list){
  echo $list;
}

你的正则表达式完全被误导了。

第一:[^...]是一个互补字符类。一个互补的字符类是一个原子,无论...是什么,它都是一组此时必须不允许的字符。例如,[^ab]将允许除ab之外的任何内容。

第二:你似乎想要能够捕捉父母之间。但是父字符(打开或关闭)是正则表达式中的一个特殊字符。因此,在您的示例中,如果$startString&nbsp(,则父级将被解释为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正则表达式修饰符告诉我们,第一个和第二个之间的任何内容都应该被视为字面量——因此&nbsp(中的父字符将被视为字面量,而不是作为组开头的元字符。

<?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函数应该与&nbsp;()}一起工作,或者任何你想要的。