質問

二つ以上の正規表現の句は任意の順序で発生する可能性があることを示す方法はありますか?例えば、XML属性は、任意の順序で記述することができます。私は、次のXMLを持っていることを言います:

<a href="home.php" class="link" title="Home">Home</a>
<a href="home.php" title="Home" class="link">Home</a>

どのように私はクラスとタイトルをチェックし、両方のケースのために働くの一致を書くのでしょうか?私は主に私はそれを行うことができますとしてだけでクラスとタイトルを一致していない、任意の順序でチェックすることができます構文を探しています。 「|」ちょうど両方の組み合わせを含むとしてそれらを接続する以外に方法はありますか?

編集:。私の好みは、私はプログラム的にそれを構築し、また、ユニット、それをテストしていますように、単一の正規表現でそれを行うことであろう。

役に立ちましたか?

解決

いいえ、私はあなたが説明するように正確である、単一のREでそれを行うための最善の方法を考えています。あなたのXMLをチェックするためにあなたに別のRE の大の番号を与えて、5つの属性を持つことができたときに残念なことに、それは非常に厄介取得します。

彼らはプログラミング言語れることを意図していないので、

一方で、私はすべてのREでこれをやっているではないでしょう。 XML処理ライブラリを使用しての昔ながらのアプローチと何が問題なのですか?

あなたがしている場合は、

のREを使用するために必要な、この答えは、おそらくあまり助けにはなりませんが、私は仕事のための適切なツールを使用して信じています。

他のヒント

あなたはXPathを検討していますか? (ここで、属性の順序は重要ではありません)。

//a[@class and @title]

は有効な一致として両方<a>ノードを選択します。唯一の注意点は、入力XHTML(整形XML)でなければならないことである。

あなたは各属性のための先読みを作成し、全体のタグのための正規表現にそれらをプラグインすることができます。例えば、タグの正規表現があり得る

<a\b[^<>]*>

あなたがXMLでこれを使用している場合、あなたはおそらくより精巧な何かをする必要があります。それ自体で、この基本正規表現は、ゼロ以上の属性を持つタグが一致します。そして、あなたが一致する属性ごとにlookheadを追加します:

(?=[^<>]*\s+class="link")
(?=[^<>]*\s+title="Home")

[^<>]*は、それが属性の先にスキャンすることができますが、それが終了角括弧を越えて見ることはできません。先読みにここに先頭の空白をマッチングすることは2つの目的があります:それは基本正規表現でそれをマッチングよりも柔軟だし、それは我々が全体の属性名と一致していることを確認してください。それらを組み合わせることで、我々が入手ます:

<a\b(?=[^<>]*\s+class="link")(?=[^<>]*\s+title="Home")[^<>]+>[^<>]+</a>

もちろん、私は明瞭にするためにいくつかの単純化の仮定を行いました。周りの空白は、単一引用符または属性値の周りに引用符なしのため、または属性値の角括弧の標識、(私が聞く合法であるが、私はそれが行わ見たことがない)に等しいため、私は許可しませんでした。 (必要であれば)正規表現醜いを行いますが、基本的な構造を変更する必要はありませんこれらのリークを塞ぐます。

あなたはタグの外に属性を引っ張ってという名前のグループを使用することができます。グループは何が必要テストを行う上で正規表現と、ループを実行します。

このような何か(未テスト、空白のための単語文字と\ sのためのワット\と.NETの正規表現の構文を使用して):

<a ((?<key>\w+)\s?=\s?['"](?<value>\w+)['"])+ />

最も簡単な方法は、<a .... >部分をピックアップ正規表現を記述し、クラスとタイトルを引き出すために、2つの以上の正規表現を記述することです。あなたは、単一の正規表現でそれをおそらく行うことができますが、それは非常に複雑であること、そしておそらく多くのエラーが発生しやすくなります。

単一の正規表現を使用すると、

のようなものが必要になります
<a[^>]*((class="([^"]*)")|(title="([^"]*)"))?((title="([^"]*)")|(class="([^"]*)"))?[^>]*>

それも有効だかどうかをチェックせずに、単に最初の手の推測です。はるかに簡単にだけ問題を分割し、征服する。

最初のアドホックソリューションは、次の手順を実行するかもしれません。

((class|title)="[^"]*?" *)+

それはすべての属性が複数回発生することができますので、これははるかに完璧からです。私は、これはアサーションとsolveableかもしれないと想像できます。あなただけの属性を抽出したい場合はしかし、これはすでにsufficentことがあります。

あなたは要素の集合の順列を一致させたい場合は、

、あなたが戻って参照すると、ゼロ幅の組み合わせを使用することができます 負の前方マッチングます。

あなたはこれらの6行のいずれかにマッチしたいとします:

123-abc-456-def-789-ghi-0AB
123-abc-456-ghi-789-def-0AB
123-def-456-abc-789-ghi-0AB
123-def-456-ghi-789-abc-0AB
123-ghi-456-abc-789-def-0AB
123-ghi-456-def-789-abc-0AB

あなたは、次の正規表現でこれを行うことができます:

/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/

後方参照(\1\2)は、あなたがあなたの前の試合を参照してみましょう、とゼロ 幅前方一致((?!...))あなたがあれば一致していないと言って、位置の一致を否定することができます この位置でマッチを含んでいました。両者を組み合わせることで、あなたの試合は合法的な順列であることを確認します 各可能性は、一度だけoccuring有する所与の要素の

ですから、例えば、ルビーでます:

input = <<LINES
123-abc-456-abc-789-abc-0AB
123-abc-456-abc-789-def-0AB
123-abc-456-abc-789-ghi-0AB
123-abc-456-def-789-abc-0AB
123-abc-456-def-789-def-0AB
123-abc-456-def-789-ghi-0AB
123-abc-456-ghi-789-abc-0AB
123-abc-456-ghi-789-def-0AB
123-abc-456-ghi-789-ghi-0AB
123-def-456-abc-789-abc-0AB
123-def-456-abc-789-def-0AB
123-def-456-abc-789-ghi-0AB
123-def-456-def-789-abc-0AB
123-def-456-def-789-def-0AB
123-def-456-def-789-ghi-0AB
123-def-456-ghi-789-abc-0AB
123-def-456-ghi-789-def-0AB
123-def-456-ghi-789-ghi-0AB
123-ghi-456-abc-789-abc-0AB
123-ghi-456-abc-789-def-0AB
123-ghi-456-abc-789-ghi-0AB
123-ghi-456-def-789-abc-0AB
123-ghi-456-def-789-def-0AB
123-ghi-456-def-789-ghi-0AB
123-ghi-456-ghi-789-abc-0AB
123-ghi-456-ghi-789-def-0AB
123-ghi-456-ghi-789-ghi-0AB
LINES

# outputs only the permutations
puts input.grep(/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/)

5つの要素の順列のために、それは以下のようになります:

/1-(abc|def|ghi|jkl|mno)-
 2-(?!\1)(abc|def|ghi|jkl|mno)-
 3-(?!\1|\2)(abc|def|ghi|jkl|mno)-
 4-(?!\1|\2|\3)(abc|def|ghi|jkl|mno)-
 5-(?!\1|\2|\3|\4)(abc|def|ghi|jkl|mno)-6/x
あなたの例では、正規表現は次のようになります。

/<a href="home.php" (class="link"|title="Home") (?!\1)(class="link"|title="Home")>Home<\/a>/
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top