web-dev-qa-db-ja.com

正規表現の件名文字列の空白を無視する方法は?

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

92
Steven

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

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

106
Sam Dufel

サムデュフェルの答えに対するスティーブンのコメントへの対応

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

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

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

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

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

8
Aurimas

検索文字列のすべての文字の間に\s*を挿入できるため、猫を探している場合はc\s*a\s*t\s*s\s*sを使用します

長いですが、もちろん文字列を動的に構築できます。

ここで動作していることがわかります: http://www.rubular.com/r/zzWwvppSpE

4
Kludge

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

\bc *a *t *s\b

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

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

catsbobcatsなどの単語内でcatsupも検索する場合は、\bアンカーを削除します。

3
Tim Pietzcker

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

次の代わりに「my cats」を検索する場合:

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

ただやる:

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

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

3
Konrad Höffner

このアプローチはautomate thisに使用できます(次のソリューション例は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'

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

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

1
Bob