1

別の別の特定の文字列で囲まれていない文字列と一致する正規表現が必要です。たとえば、次の状況では、コンテンツを2つのグループに分割します。1)2番目の{Switch}の前のコンテンツと2)2番目の{Switch}の後のコンテンツ。{my_string}で囲まれているため、最初の{Switch}とは一致しません。文字列は常に次のようになります(つまり、{my_string}ここにあるコンテンツ{/ my_string})

Some more  
  {my_string}
  Random content
  {Switch} //This {Switch} may or may not be here, but should be ignored if it is present
  More random content
  {/my_string}
Content here too
{Switch}
More content

これまでのところ、私が知っている以下のものはまったく近くないものを手に入れました:

(.*?)\{Switch\}(.*?)

[^](演算子ではない)を特定の文字列と別の文字で使用する方法がわかりません。

4

5 に答える 5

2

正規表現を使用して文法を解析しようとしているようです。正規表現は非常に苦手です。文字列をそれを構築するトークンに分解するパーサーを作成してから、そのツリーを処理する方がよい場合があります。

おそらくhttp://drupal.org/project/grammar_parserのようなものが役立つかもしれません。

于 2012-04-09T21:21:34.033 に答える
1
$regex = (?:(?!\{my_string\})(.*?))(\{Switch\})(?:(.*?)(?!\{my_string\}));
/* if "my_string" and "Switch" aren't wrapped by "{" and "}" just remove "\{" and "\}" */
$yourNewString = preg_replace($regex,"$1",$yourOriginalString);

これはうまくいくかもしれません。それを知ることはできませんが、後で更新します!これがあなたが探しているものであるかどうかはわかりませんが、複数の文字を否定するために、正規表現の構文は次のとおりです。

(?!yourString) 

これは「ネガティブ先読みアサーション」と呼ばれます。

/編集:

これは機能し、trueを返すはずです。

$stringMatchesYourRulesBoolean = preg_match('~(.*?)('.$my_string.')(.*?)(?<!'.$my_string.') ?('.$switch.') ?(?!'.$my_string.')(.*?)('.$my_string.')(.*?)~',$yourString);
于 2012-04-09T21:31:14.737 に答える
1

ポジティブな先読みと後読みのアサーションを試すことができます(http://www.regular-expressions.info/lookaround.html)

次のようになります。

$content = 'string of text before some random content switch text some more random content string of text after';
$before  = preg_quote('String of text before');
$switch  = preg_quote('switch text');
$after   = preg_quote('string of text after');
if( preg_match('/(?<=' $before .')(.*)(?:' $switch .')?(.*)(?=' $after .')/', $content, $matches) ) {
    // $matches[1] == ' some random content '
    // $matches[2] == ' some more random content '
}
于 2012-04-09T21:39:41.390 に答える
1

この単純な関数を試してください。

関数find_content()

function find_content($doc) {
  $temp = $doc;
  preg_match_all('~{my_string}.*?{/my_string}~is', $temp, $x);
  $i = 0;
  while (isset($x[0][$i])) {
    $temp = str_replace($x[0][$i], "{REPL:$i}", $temp);
    $i++;
    }
  $res = explode('{Switch}', $temp);
  foreach ($res as &$part) 
    foreach($x[0] as $id=>$content)
      $part = str_replace("{REPL:$id}", $content, $part);
  return $res;
  }

このように使用してください

$content_parts = find_content($doc); // $doc is your input document
print_r($content_parts);

出力(あなたの例)

Array
(
    [0] => Some more
{my_string}
Random content
{Switch} //This {Switch} may or may not be here, but should be ignored if it is present
More random content
{/my_string}
Content here too

    [1] => 
More content
)
于 2012-04-09T22:14:34.227 に答える
0

PHPPEGをご覧ください。PHPで書かれた小さなパーサーです。独自の文法を記述して解析することができます。あなたの場合、それは非常に単純になるでしょう。

文法構文と構文解析の方法はすべてREADME.mdで説明されています

readmeからの抜粋:

  token*  - Token is optionally repeated
  token+ - Token is repeated at least one
  token? - Token is optionally present

トークンは次のようになります:

 - bare-words, which are recursive matchers - references to token rules defined elsewhere in the grammar,
 - literals, surrounded by `"` or `'` quote pairs. No escaping support is provided in literals.
 - regexs, surrounded by `/` pairs.
 - expressions - single words (match \w+)

サンプル文法:(ファイルEqualRepeat.peg.inc)

class EqualRepeat extends Packrat {
/* Any number of a followed by the same number of b and the same number of c characters
 * aabbcc - good
 * aaabbbccc - good
 * aabbc - bad
 * aabbacc - bad
 */

/*Parser:Grammar1
A: "a" A? "b"
B: "b" B? "c"
T: !"b"
X: &(A !"b") "a"+ B !("a" | "b" | "c")
*/
}
于 2012-04-09T21:46:44.760 に答える