0

我问了一个类似的问题,但由于过于宽泛而被关闭。基本上,我有很多这样的问题。我希望只是问一个会更容易。我尝试了一些不同的方法来解决这个问题,但它们都没有真正起作用。

我有一个包含大量数据的文本文件。我感兴趣的唯一数据位于两个括号“(”“)”之间。我想知道如何将括号之间的每个信息实例放入数组中。

我现在使用的代码返回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;
}
4

2 回答 2

2

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

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

第二:您似乎希望能够在括号之间捕获。但是括号(打开或关闭)是正则表达式中的特殊字符。因此,在您的示例中, if $startStringis &nbsp(,括号将被解释为正则表达式元字符。

第三:不幸的是,这不能用正则表达式解决,而是嵌套$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一个和第二个之间的任何内容都应该被视为文字 - 因此括号 in&nbsp(将被视为字面意思,而不是组开始元字符。

于 2011-12-30T02:06:01.113 回答
1
<?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 将是一个数组数组。我相信默认情况下,索引零将包含所有完全匹配。index one 将包含第一个子模式匹配。

C: 这只有在你试图匹配的子模式中永远找不到 $endString 时才有效。比如说,如果你期望 (matc(fF)) 给你 matc(fF),它不会。它会给你 match(fF. 如果你想在这种情况下得到前一个结果,你需要一个更强大的解析器。

编辑:这里的 get_between 函数也应该与&nbsp;(and一起使用)},或者你想要的任何其他东西。

于 2011-12-30T02:17:53.390 回答