3

正規表現を使用してテキストに一致させようとしています。

次のパターンは、私が収集しようとしているものです。

@Identifier('VariableA', 'VariableB', 'VariableX', ..., 'VariableZ')

2 つまたは 3 つの固定セットではなく、動的な数の変数を取得したいと考えています。これを行う方法はありますか?既存の正規表現があります:

\@(\w+)\W+(\w+)\W+(\w+)\W+(\w+)

これにより、識別子と最大 3 つの変数がキャプチャされます。

編集:それは私だけですか、それとも正規表現は私が考えているほど強力ではありませんか?

4

4 に答える 4

3

scanこういうことに使いたい。基本的なパターンは次のとおりです。

s.scan(/\w+/)

これにより、単語文字のすべての連続したシーケンスの配列が得られます。

>> "@Identifier('VariableA', 'VariableB', 'VariableX', 'VariableZ')".scan(/\w+/)
=> ["Identifier", "VariableA", "VariableB", "VariableX", "VariableZ"]

あなたはあなたがそれらを取り巻く任意のものであなたのパターンの複数のインスタンスを持っているかもしれないと言います。あなたはネストされたsでそれを扱うことができますscan

s.scan(/@(\w+)\(([^)]+?)\)/).map { |m| [ m.first, m.last.scan(/\w+/) ] }

これにより、配列の配列が得られます。各内部配列には、最初の要素として「識別子」部分があり、2番目の要素の配列として「変数」部分があります。例えば:

>> s = "pancakes @Identifier('VariableA', 'VariableB', 'VariableX', 'VariableZ') pancakes @Pancakes('one','two','three') eggs"
>> s.scan(/@(\w+)\(([^)]+?)\)/).map { |m| [ m.first, m.last.scan(/\w+/) ] }
=> [["Identifier", ["VariableA", "VariableB", "VariableX", "VariableZ"]], ["Pancakes", ["one", "two", "three"]]]

「変数」ビット内でエスケープされた引用符に直面している可能性がある場合は、より複雑なものが必要になります。


式に関するいくつかの注意:

@            # A literal "@".
(            # Open a group
  \w+        # One more more ("+") word characters ("\w").
)            # Close the group.
\(           # A literal "(", parentheses are used for group so we escape it.
(            # Open a group.
  [          # Open a character class.
    ^)       # The "^" at the beginning of a [] means "not", the ")" isn't escaped because it doesn't have any special meaning inside a character class.
  ]          # Close a character class.
  +?         # One more of the preceding pattern but don't be greedy.
)            # Close the group.
\)           # A literal ")".

[^)]+?ここでは実際には必要ありませんが、必要なだけ[^)]+ですが、通常はそれが意味するので、欲張りでない形式を習慣的に使用します。@Identifierグループ化は、とパーツを分離するために使用されるVariableため、目的のネストされた配列出力を簡単に取得できます。

于 2011-10-28T02:25:20.180 に答える
0

したがって、識別子と任意の数の変数の両方をキャプチャする方法があるかどうかを尋ねています。これは、キャプチャをサポートする正規表現エンジンでのみ実行できます。ここで、キャプチャキャプチャグループは同じものではないことに注意してください。すべての「変数」を覚えておきたい。これは、単純なキャプチャグループでは実行できません。

Rubyがこれをサポートしているかどうかはわかりませんが、.NETと新しいPERL6がサポートしていると確信しています。

あなたの場合、2つの正規表現を使用できます。識別子をキャプチャするための1つ。^\s*@(\w+)

もう1つは、すべての変数をキャプチャします。result = subject.scan(/'[^']+'/)

于 2011-10-28T02:21:03.940 に答える
0

しかし、アレックスは、あなたが同じものを 4 回キャプチャしたかったと考えています。同じパターンで異なるものをキャプチャしたい場合は、次の 2 つのことを考慮する必要があります。

反復。perlでは、あなたは言うことができます

while ($variable =~ /regex/g) {

「g」は「global」を表し、正規表現が呼び出されるたびに /next/ インスタンスに一致することを意味します。

もう 1 つのオプションは再帰です。次のように正規表現を記述します。

/(what you want)(.*)/

次に、配列にプッシュできる最初のものを含む後方参照 1 と、一致しなくなるまで再帰する後方参照 2 があります。

于 2011-10-28T01:41:34.160 に答える
0

を単純に使用できます(\w+)

入力文字列が与えられた場合 @Identifier('VariableA', 'VariableB', 'VariableX', 'VariableZ')

結果は次のようになります。

  1. Identifier
  2. VariableA
  3. VariableB
  4. VariableX
  5. VariableZ

これは、任意の数の変数に対して機能します。

将来の参考のために、 Rubularで正規表現のアイデアを試すのは簡単で楽しいものです。

于 2011-10-28T01:43:07.377 に答える