Як ігнорувати пробіли у рядку предмета регулярного виразу?


107

Чи є простий спосіб ігнорувати пробіл білого кольору в цільовому рядку під час пошуку відповідностей, використовуючи шаблон регулярного вираження? Наприклад, якщо мій пошук "котів", я б хотів, щоб "c ats" або "ca ts" відповідали. Я не можу заздалегідь викреслити пробіл, тому що мені потрібно знайти індекс початку та кінця матчу (включаючи будь-який пробіл), щоб виділити цю відповідність, і будь-який пробіл повинен бути там для форматування.

Відповіді:


124

Ви можете вставити необов’язкові символи пробілів \s*між усіма іншими символами у вашому регексе. Незважаючи на те, що він наданий, він буде трохи тривалим.

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


Дякую, це здається, що це шлях. Але я просто зрозумів, що бажаю лише необов'язкових символів пробілу, якщо вони слідують за новим рядком. Так, наприклад, "c \ n ats" або "ca \ n ts" повинні відповідати. Але не хотілося б, щоб "c ats" відповідав, якщо немає нового рядка. Будь-які ідеї, як це можна зробити?
Стівен

@Steven, подивіться, як я це зробив нижче, ви можете легко адаптувати моє рішення до таких конкретних випадків.
Боб

@ Кріс Я думаю, це регулярний вираз так строго тільки для кішок, вона також може бути писати для будь-якого пошуку листів , як це: ^([a-z]\s*)+$
Sandeep Каур

9

Звертаючись до коментаря Стівена до відповіді Сема Дафеля

Дякую, це здається, що це шлях. Але я просто зрозумів, що бажаю лише необов'язкових символів пробілу, якщо вони слідують за новим рядком. Так, наприклад, "c \ n ats" або "ca \ n ts" повинні відповідати. Але не хотілося б, щоб "c ats" відповідав, якщо немає нового рядка. Будь-які ідеї, як це можна зробити?

Для цього слід зробити фокус:

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

На цій сторінці перегляньте всі різні варіанти "котів", які відповідають цьому.

Ви також можете вирішити це за допомогою умовних умов , але вони не підтримуються у смаку JavaScript регулярного виразу.


3
Так дуже потворно. Має бути кращий спосіб.
james.garriss

Ви можете зробити його більш читабельним у синтаксисі 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якір, якщо ви також хочете знайти їх catsу словах, таких як bobcatsабо catsup.


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'

Якщо ви хочете піти далі, ви можете сконструювати об’єкт відповідності та повернути його замість цього, тому використання цього помічника буде більш зручним.

І ефективність цієї функції, звичайно, також може бути оптимізована. Цей приклад - просто показати шлях до рішення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.