Regex: Вкажіть "пробіл або початок рядка" та "пробіл або кінець рядка"


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
Зауважте, що в більшості реалізацій regexp \bє стандартним лише ASCII , тобто немає підтримки Unicode. Якщо вам потрібно відповідати слова unicode, у вас немає іншого вибору, крім цього: stackoverflow.com/a/6713327/1329367
Ман


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

4
Буде \bрозглянути інші символи - наприклад, " ." як переривники слів, тоді як запитувач спеціально сказав "пробіл". @ рішення Горді здається кращим.
Михайло Т.

65

(^|\s)відповідатиме пробіл або початок рядка та ($|\s)пробіл або кінець рядка. Разом це:

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

4
це єдине, що працює для мене. дякую @gordy
robsonrosa

2
Якщо ви використовуєте цей шаблон для заміни, не забудьте зберегти пробіли в результаті, що заміняється, замінивши його $1string$2.
Ман

Це єдине, що працює і для мене. Межі слів ніби ніколи не роблять те, що я хочу. Для одного вони відповідають деяким символам, окрім пробілів (як тире). Це вирішило це для мене, тому що я намагався поставити $і ^в клас персонажів, але це показує, що їх можна просто помістити в звичайну групу зразків.
Початок

18

Ось що я б використав:

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

Іншими словами, співставляйте "stackoverflow", якщо йому не передує символ, який не є пробілом, і не супроводжується символом, який не є пробілом.

Це акуратніше (IMO), ніж підхід "пробіл чи якор", і він не передбачає, що рядок починається і закінчується символами слова, як це \bробить підхід.


1
гарне пояснення того, для чого це використовувати. Я б вибрав це, однак рядок, що тестується, ЗАВЖДИ єдиний рядок.
анонімний-один

7

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

\bstackoverflow\b

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