4

多数のテキスト行を含むファイルがあり、複数の単語を含む行のみを照合したいと考えています。すべての単語が行に含まれている必要がありますが、順序は問いません

したがって、onetwothreeに一致させたい場合は、以下の最初の 2 行が一致します。

three one four two <-- match
four two one three <-- match
one two four five
three three three

QRegExp を使用してこれを行うことはできますか (テキストを分割し、単語ごとに各行を個別にテストする必要はありません)。

4

2 に答える 2

2

はい、可能です。先読みを使用します。これにより、対象文字列の次の部分が実際に消費されることなくチェックされます。つまり、先読みが終了すると、正規表現エンジンは開始した場所に戻り、別の先読みを実行できます (もちろん、この場合は文字列の先頭から使用します)。これを試して:

^(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)[^\r\n]*$

否定された文字クラス[^\r\n]により、行末を決して見過ごすことができないことが保証されます。先読みは実際には一致のために何も消費しないため、[^\r\n]*最後 (先読みの後) と$行の最後に を追加します。$実際、 の貪欲さのために , を省略することもできますが、*その方が表現の意味がもう少し明確になると思います。

この正規表現は必ず複数行モードで使用してください (行頭^と一致するように)。$

編集:

申し訳ありませんが、QRegExpは複数行モードをサポートしていないようですm:

QRegExp には Perl の /m オプションに相当するものはありませんが、入力を行に分割したり、改行を検索する正規表現でループしたりするなど、さまざまな方法でエミュレートできます。

文字列を行に分割することも推奨されていますが、これは避けたいことです。

QRegExp は後読みもサポートしていないため (エミュレートに役立ちますm)、他のソリューションはもう少しトリッキーです。あなたは一緒に行くことができます

(?:^|\r|\n)(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)([^\r\n]*)

次に、必要な行が capture group にある必要があります1。しかし、文字列を行に分割すると、これよりも読みやすいコードになると思います。

于 2012-12-03T20:28:42.880 に答える