0

同様の質問をしましたが、広すぎるため閉鎖されました。基本的に、私はこのような質問をたくさん持っています。質問するだけで簡単になることを願っています。私はこれを解決するためにいくつかの異なる方法を試しましたが、実際にはどれも機能しません。

大量のデータを含むテキストファイルがあります。私が興味を持っている唯一のデータは、2つの括弧 "(" ")"の間にあります。角かっこの間にある情報の各インスタンスを配列に取得する方法を考えています。

私が今使用しているコードは次を返します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]ab

第二に:あなたは親の間を捕らえることができるようになりたいようです。ただし、パレン(開くまたは閉じる)は正規表現の特殊文字です。したがって、あなたの例で$startStringは、がの場合&nbsp(、パレンは正規表現のメタ文字として解釈されます。

3番目:残念ながら、これは正規表現では解決できませんが、ネストされ$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、1番目と2番目の間のすべてをリテラルとして処理する必要があることを示します。したがって、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";
}

私はこれをしました、そしてそれはうまくいくようです。(明らかに、$ myFile割り当て行をfile_get_contentsステートメントに置き換える必要があります。)いくつかのこと:

A:変数の置換は一重引用符では発生しません。したがって、preg_replace_all正規表現は結果として機能しません。文字列の代わりに$startStringを式に追加するため(。(一致した文字列の最後にある}のチェックも削除しました。必要に応じて\\}、終了区切り文字の直前に追加し直してください。)

B:$listは配列の配列になります。デフォルトでは、インデックスゼロにはすべての完全一致が含まれると思います。インデックス1には、最初のサブパターンの一致が含まれます。

C:これは、一致させようとしているサブパターン内に$endStringが見つからない場合にのみ機能します。たとえば、(matc(fF))がmatc(fF)を提供することを期待している場合は、そうではありません。これにより、match(fF。この場合に前者の結果を取得する場合は、より強力なパーサーが必要になります。

編集:ここでのget_between関数は、および、またはその他の必要なもの&nbsp;(と連携して機能するはずです。)}

于 2011-12-30T02:17:53.390 に答える