1

LaTeX では、この式\o{a}{b}は、演算子 'o' が 2 つの引数 a と b を取ることを意味します。LaTeX も を受け入れます\o{a}。この場合、2 番目の引数を空の文字列として扱います。

ここで、正規表現\\\\o\{([\s\S]*?)\}\{([\s\S]*?)\}を文字列と照合しようとします\o{a}\o{a}{b}。そうでない場合は、文字列全体が一致すると誤解します。(この文字列の正しい解釈は、部分文字列\o{a}{b}のみが一致するということです。) ポイントは、最初の } の後に { 以外の何かがある場合、それは一致しないことを PHP に認識させる方法を知る必要があるということです。

どうすればいいですか?

編集: 演算子の引数には、記号\{を含めることができます}。しかし、この場合、文字列全体が一致しない理由は、中括弧がa}\o{aLaTeX の規則に準拠していないためです (たとえば、 の{前に来る必要があります})。そのためa}\o{a、演算子の引数にすることはできません...

Edit2 :一方、有効な引数である\o{{a}}{b}ため、一致する必要があります。{a}

4

3 に答える 3

2

私は次のようなことを提案します:

$s = '\\o{a}\\o{a}{b}';
echo "$s\n";  # Check string
preg_match('~\\\o(\{(?>[^{}\\\]++|(?1)|\\\.)+\}){2}~', $s, $match);
print_r($match);

イデオンデモ

正規表現:

  • 再帰を使用してネストされたブレースを処理し、
  • バックスラッシュも ([^{}\\\]および\\\.) を使用して、構文中括弧にリテラル中括弧を使用しないようにします。

\\\o             # Matches \o
(                # Recursive group to be
  \{             # Matches {
  (?>            # Begin atomic group (just a group that makes the regex faster)
     [^{}\\\]++  # Any characteres except braces and backslash
  |
     (?1)        # Or recurse the outer group
  |
     \\\.        # Or match an escaped character
  )+             # As many times as necessary
  \}             # Closing brace
){2}             # Repeat twice

現在の正規表現の問題は、この部分が一致\\\\o\{([\s\S]*?)すると、次に来るものを探そうとすること\}です。そこでは、怠惰な量指定子を使用しているか貪欲な量指定子を使用しているかは問題ではありません。}実際\}の正規表現が入る前に、何らかの形で一致するのを防ぐ必要があります。

そのため、使用する必要が[^{}]あり、実際には内部にネストされたブレースを使用できるため、再帰を使用するのに理想的な状況です。

于 2014-06-11T20:50:17.557 に答える
1

ネストされた中括弧の可能性に対処するには、再帰機能を使用する必要があります。

$pattern = <<<'EOD'
~
\\o({(?>[^{}]+|(?-1))*}){2}
~x
EOD;

ここ(?-1)で、最後のキャプチャ グループのサブパターンへの参照です。

于 2014-06-11T20:41:12.833 に答える
0

^アンカーの使用を検討する必要があると思います$

$pattern = '/^\\o\{.*\}(\{.*\})?$/';

aとの許容値を何と考えているのかわかりません。ここで適切なクラスにb置き換えることができます。.*

これにより、\0{a}または\o{a}{b}形式のいずれかが許可されます。\o{a}{b}これに変更のみを一致させるには:

$pattern = '/^\\o\{.*\}\{.*\}$/';

最後の編集に基づいて、他の回答に記載されている.*ように上記を置き換えることをお勧めします。[^{]*

于 2014-06-11T20:32:36.883 に答える