正規表現のサブジェクト文字列の空白を無視する方法は?


107

正規表現パターンを使用して一致を検索するときに、ターゲット文字列の空白を無視する簡単な方法はありますか?たとえば、「猫」を検索する場合は、「c ats」または「ca ts」と一致させます。一致を強調表示するために一致の開始インデックスと終了インデックス(空白を含む)を見つける必要があり、フォーマットの目的で空白が必要なため、事前に空白を取り除くことはできません。

回答:


124

\s*正規表現では、オプションの空白文字を他のすべての文字の間に挿入できます。許可されていますが、少し長くなります。

/cats/ -> /c\s*a\s*t\s*s/


ありがとう、それが進むべき道のように聞こえます。しかし、改行に続く場合にのみオプションの空白文字が必要であることを認識しました。たとえば、「c \ n ats」または「ca \ n ts」は一致する必要があります。ただし、改行がない場合は「c ats」を一致させたくないでしょう。それがどのように行われるかについてのアイデアはありますか?
Steven

@スティーブン、以下で私がどのようにそれを行ったかを見てください、あなたは私のソリューションをそのような特定のケースに簡単に適応させることができます。
ボブ

@chris私が思うに、この正規表現は猫だけにとても厳格で、次のような文字の検索のために書くこともできます: ^([a-z]\s*)+$
Sandeep Kaur

9

スティーブンのコメントをサム・デュフェルの回答に向けて

ありがとう、それが進むべき道のように聞こえます。しかし、改行に続く場合にのみオプションの空白文字が必要であることを認識しました。たとえば、「c \ n ats」または「ca \ n ts」は一致する必要があります。ただし、改行がない場合は「c ats」を一致させたくないでしょう。それがどのように行われるかについてのアイデアはありますか?

これでうまくいくはずです:

/c(?:\n\s*)?a(?:\n\s*)?t(?:\n\s*)?s/

これが一致する「猫」のさまざまなバリエーションについては、このページを参照してください

条件文を使用してこれを解決することもできますが、それらは正規表現のJavaScriptフレーバーではサポートされていません。


3
とても醜い。もっと良い方法があるはずです。
james.garriss 2015年

あなたが(技術は他の言語で動作しますが)JS構文でそれを読みやすくできますnew RegExp('cats'.split('').join('(?:\n\s*)?'))
brianary

7

受け入れられた答えは技術的に正しいですが、可能であれば、より現実的なアプローチは、正規表現と検索文字列の両方から空白を取り除くことです。

「私の猫」を検索する場合は、次の代わりに:

myString.match(/m\s*y\s*c\s*a\*st\s*s\s*/g)

ただやる:

myString.replace(/\s*/g,"").match(/mycats/g)

警告:すべてのスペースを空の文字列に置き換えるだけでは正規表現でこれを自動化できません。これは、否定が発生するか、正規表現が無効になる可能性があるためです。


5

あなたは\s*検索文字列のすべての文字の間に置くことができるので、あなたが猫を探しているならあなたは使うでしょうc\s*a\s*t\s*s\s*s

長いですが、もちろん動的に文字列を作成することもできます。

あなたはここでそれが働いているのを見ることができます:http : //www.rubular.com/r/zzWwvppSpE


3

スペースのみを許可する場合は、

\bc *a *t *s\b

それを行う必要があります。タブも許可するには、

\bc[ \t]*a[ \t]*t[ \t]*s\b

またはのような単語内で\bも検索する場合は、アンカーを削除します。catsbobcatscatsup


1

このアプローチは、これを自動化するために使用できます(次の例示的なソリューションはpythonですが、明らかに任意の言語に移植できます)。

事前に空白を取り除き、空白以外の文字の位置を保存しておくと、後でそれらを使用して、次のように元の文字列で一致する文字列の境界位置を見つけることができます。

def regex_search_ignore_space(regex, string):
    no_spaces = ''
    char_positions = []

    for pos, char in enumerate(string):
        if re.match(r'\S', char):  # upper \S matches non-whitespace chars
            no_spaces += char
            char_positions.append(pos)

    match = re.search(regex, no_spaces)
    if not match:
        return match

    # match.start() and match.end() are indices of start and end
    # of the found string in the spaceless string
    # (as we have searched in it).
    start = char_positions[match.start()]  # in the original string
    end = char_positions[match.end()]  # in the original string
    matched_string = string[start:end]  # see

    # the match WITH spaces is returned.
    return matched_string

with_spaces = 'a li on and a cat'
print(regex_search_ignore_space('lion', with_spaces))
# prints 'li on'

さらに進めたい場合は、matchオブジェクトを作成してそれを返すことができるため、このヘルパーを使用するとさらに便利です。

もちろん、この関数のパフォーマンスも最適化できます。この例は、ソリューションへのパスを示すためのものです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.