2

この正規表現を Java に変換しようとしています。

^(\s*([<>]=?)?\s*!?(?:(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*

もちろん、条件がサポートされていないことは知っています。直訳すると例外が発生します。したがって、問題を解決する方法についてのアイデアを得たいと思います。

ありがとう、

4

1 に答える 1

2

まず、パターンにバグがあると思います:

^(\s*([<>]=?)?\s*!?(?:(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*

グループ 2 のテストの前にコロンがあるようです。それは次のようにする必要があります。

^(\s*([<>]=?)?\s*!?(?(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*

しかし、私にはあまり意味をなさない奇妙な点が他にもあります。モードであなたのパターンを書き直して、(?x)それを解き明かし、何らかの意味を理解できるようにします. [0-9\*]ああ、条件分岐の or-branch にある不要なバックスラッシュを取り除きます[0-9*]

それはこれを生成します:

(?x)                       # enable comments and whitespace
^                          # anchor to beginning of string
(                          # begin GROUP #1 {
    \s *                   #     any amount of whitespace, including none
    (                      #     begin GROUP #2 {
        [<>]               #        exactly one of either kind of pointy bracket
        = ?                #        optional equals sign
    ) ?                    #     } end GROUP #2, make optional
    \s *                   #     any amount of whitespace, including none
    ! ?                    #     optional exclamation point
    (?(2)                  #     if GROUP#2 is defined {
          [0-9]   {1,5}    #         then: 1-5× ASCII digits
     |    [0-9*]  {1,5}    #         else: 1-5× of either star or ASCII digit
    )                      #     } end ifdef GROUP#2
    \s *                   #     any amount of whitespace, including none
    (                      #     begin GROUP#3 {
        &                  #        either:  an ampersand
      | $                  #        or else: end of string
    )                      #     } end GROUP#3
) *                        # } end GROUP #1, make optional but allow repeats

私が知る限り、それはあなたが実際にやろうとしていることです。なぜあなたがそれをしているのか、私にはわかりません。そこには奇妙に見えるものがあるからです。

たとえば、なぜ最初のキャプチャ グループに繰り返し演算子を適用するのでしょうか。すべての繰り返しを保持するわけではなく、最後の繰り返しのみを保持します。

もう 1 つの質問は、グループ 1 の繰り返しをゼロにする理由です。*可能性のあるすべての文字列がパターンに一致するのと 同じように、可能性のあるすべての文字列^a*もパターンに一致します。これはあまり役に立たないようです。

最後に、アンパサンドまたは文字列の終わりのいずれかを持つことは、そこの終わりに向かってかなり奇妙です.

元の投稿者が彼の意図を明確にするなら、私はこれを Java 正規表現で動作するものに翻訳します。Java 正規表現は、ここで使用した条件付き構造をサポートしていません。Perl、PHP、PCRE、および C ♯</sup> すべてをサポートするものです。サポートしますが、Java はサポートしません。(とにかく、これはどの言語から出てきたのですか?) それを行う方法は、or 分岐を使用して条件分岐を展開することです。両方のケースがカバーされます。

全体のパターンについては少し疑わしいです。一致するはずのいくつかのサンプル入力をいただければ幸いです。

私が強調しきれないことの 1 つは/x、私が提供した正規表現の拡張バージョンが、これらを記述する唯一の方法であるということです。空白、インデント、論理グループ、およびコメントのない、このようなグックは完全に容認できません。このようなものは、コード レビューに合格するべきではありません。彼らは忌まわしきものです。

そして、そうである必要はありません。/xこのような長さと複雑さの正規表現には常に mode を使用するようお願いします。あなたの後に来る人たちのことを考えてみてください。できればそうなる前に。

最後に、なぜこれは、はるかに堅牢な覚えやすい名前付きグループの代わりに番号付きグループを使用するのか疑問に思います。さらに、Java 7 はついに名前付きグループをサポートするため、そこで妥協する必要はありません。

于 2012-06-04T02:58:40.217 に答える