1. ホーム
  2. regex

[解決済み] 有効な正規表現を検出するための正規表現はありますか?

2022-03-20 14:02:27

質問

有効な正規表現を別の正規表現で検出することは可能でしょうか? 可能な場合、以下にコード例を示します。

どのように解決するのですか?

/
^                                             # start of string
(                                             # first group start
  (?:
    (?:[^?+*{}()[\]\\|]+                      # literals and ^, $
     | \\.                                    # escaped characters
     | \[ (?: \^?\\. | \^[^\\] | [^\\^] )     # character classes
          (?: [^\]\\]+ | \\. )* \]
     | \( (?:\?[:=!]|\?<[=!]|\?>)? (?1)?? \)  # parenthesis, with recursive content
     | \(\? (?:R|[+-]?\d+) \)                 # recursive matching
     )
    (?: (?:[?+*]|\{\d+(?:,\d*)?\}) [?+]? )?   # quantifiers
  | \|                                        # alternative
  )*                                          # repeat content
)                                             # end first group
$                                             # end of string
/

これは再帰的な正規表現であり、多くの正規表現エンジンではサポートされていません。PCREベースのものはサポートしているはずです。

空白とコメントなし。

/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/


.NETは再帰を直接サポートしていません。(そのため (?1)(?R) を構成する)。再帰はバランスの取れたグループを数えるように変換されなければならないだろう。

^                                         # start of string
(?:
  (?: [^?+*{}()[\]\\|]+                   # literals and ^, $
   | \\.                                  # escaped characters
   | \[ (?: \^?\\. | \^[^\\] | [^\\^] )   # character classes
        (?: [^\]\\]+ | \\. )* \]
   | \( (?:\?[:=!]
         | \?<[=!]
         | \?>
         | \?<[^\W\d]\w*>
         | \?'[^\W\d]\w*'
         )?                               # opening of group
     (?<N>)                               #   increment counter
   | \)                                   # closing of group
     (?<-N>)                              #   decrement counter
   )
  (?: (?:[?+*]|\{\d+(?:,\d*)?\}) [?+]? )? # quantifiers
| \|                                      # alternative
)*                                        # repeat content
$                                         # end of string
(?(N)(?!))                                # fail if counter is non-zero.

コンパクトにした。

^(?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>|\?<[^\W\d]\w*>|\?'[^\W\d]\w*')?(?<N>)|\)(?<-N>))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*$(?(N)(?!))

コメントより

これで置換や翻訳が検証されるのでしょうか?

置換や翻訳の正規表現部分のみを検証します。 s/<this part>/.../

<ブロッククオート

有効な正規表現文法をすべて正規表現でマッチングさせることは理論的に不可能です。

PCREのように再帰をサポートする正規表現エンジンであれば可能ですが、それはもう正規表現とは呼べません。

確かに、quot;recursive regular expression" は正規表現ではありません。しかし、これは正規表現エンジンの拡張としてよく受け入れられているものである...。皮肉なことに、この拡張正規表現は拡張正規表現にマッチしないのです。

理論上、理論と実践は同じです。正規表現を知っている人ならほとんど誰でも、正規表現は再帰をサポートしていないことを知っています。しかし、PCREや他のほとんどの実装は、基本的な正規表現をはるかに超えるものをサポートしています。

<ブロッククオート

シェルスクリプトの grep コマンドでこれを使用すると、いくつかのエラーが表示されます... grep: 無効な内容の{} . 私は、正規表現を含むすべてのファイルを見つけるためにコードベースをgrepすることができるスクリプトを作成しています。

このパターンは再帰的正規表現と呼ばれる拡張を利用したものです。これはPOSIXフレーバーのregexではサポートされていません。PCRE regex を有効にするには、-P スイッチを使用してください。

<ブロッククオート

Regexそのものは正規言語ではないので、正規表現でパースすることはできません..."。

これは古典的な正規表現に当てはまります。最近の実装では再帰を許可しているものもあり、文脈自由言語になっていますが、このタスクではやや冗長になります。

<ブロッククオート

なるほど、マッチングするのは []()/\ .などの特殊な正規化文字があります。特殊文字以外を許可している箇所はありますか?この場合 ^(?:[\.]+)$ とは異なり ^abcdefg$ . これは有効な正規表現です。

[^?+*{}()[\]\\|] は、他のどの構文にも属さない、任意の一文字にマッチします。これには、リテラル ( a - z )、および特定の特殊文字( ^ , $ , . ).