Регулярное выражение: укажите «пробел или начало строки» и «пробел или конец строки».


127

Представьте, что вы пытаетесь сопоставить шаблон "stackoverflow".

Вам нужно следующее:

 this is stackoverflow and it rocks [MATCH]

 stackoverflow is the best [MATCH]

 i love stackoverflow [MATCH]

 typostackoverflow rules [NO MATCH]

 i love stackoverflowtypo [NO MATCH]

Я знаю, как разобрать stackoverflow, если на обоих сайтах есть пробелы, используя:

/\s(stackoverflow)\s/

То же самое, если оно находится в начале или в конце строки:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Но как указать «пробел или конец строки» и «пробел или начало строки» с помощью регулярного выражения?

Ответы:


172

Вы можете использовать любое из следующего:

\b      #A word break and will work for both spaces and end of lines.
(^|\s)  #the | means or. () is a capturing group. 


/\b(stackoverflow)\b/

Кроме того, если вы не хотите включать пробел в свой матч, вы можете использовать просмотр назад / вперед.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.

8
\b- утверждение нулевой ширины; он никогда не потребляет никаких символов. Нет необходимости оборачивать это взглядом.
Алан Мур

2
Обратите внимание , что в большинстве реализаций регулярных выражений, \bявляется стандартным ASCII только , что не сказать, никакой поддержки юникода. Если вам нужно сопоставить слова Unicode, у вас нет другого выбора, кроме как использовать это вместо: stackoverflow.com/a/6713327/1329367
Mahn

4
Более простой способ исключить групповой выбор из матча(?:^|\s)
user2426679

7
для python замените (?<=\s|^)на (?:(?<=\s)|(?<=^)). В противном случае вы получитеerror: look-behind requires fixed-width pattern
user2426679

4
\bРассмотрят другие символы - такие , как « .» как слово выключатели, в то время как Аскер конкретно сказал «пространство». Решение @gordy кажется лучше.
Михаил Т.

66

(^|\s)будет соответствовать пробелу или началу строки и ($|\s)пробелу или концу строки. Вместе это:

(^|\s)stackoverflow($|\s)

4
это единственное, что у меня работает. спасибо @gordy
robsonrosa

2
Если вы используете этот шаблон для замены, не забудьте сохранить пробелы в заменяемом результате, заменив его шаблоном $1string$2.
Mahn

Это единственное, что мне подходит. Кажется, что границы слов никогда не делают того, что я хочу. Во-первых, они соответствуют некоторым символам помимо пробелов (например, тире). Это решило проблему для меня, потому что я пытался поместить $и ^в класс символов, но это показывает, что их можно просто поместить в обычную группу шаблонов.
felwithe

18

Вот что я бы использовал:

 (?<!\S)stackoverflow(?!\S)

Другими словами, соответствует «stackoverflow», если ему не предшествует непробельный символ и за ним не следует непробельный символ.

Это более аккуратно (ИМО), чем подход «пробел или привязка», и он не предполагает, что строка начинается и заканчивается символами слова, как в этом \bподходе.


1
хорошее объяснение того, зачем это использовать. я бы выбрал это, однако тестируемая строка ВСЕГДА является одной строкой.
anonymous-one

7

\b совпадает с границами слова (без фактического совпадения каких-либо символов), поэтому следующее должно делать то, что вы хотите:

\bstackoverflow\b

Для Python это помогает указать необработанную строку , напримерmystr = r'\bstack overflow\b'
Acumenus
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.