Regex соответствует только целым словам


92

У меня есть выражение регулярного выражения, которое я использую, чтобы найти все слова в заданном блоке содержимого без учета регистра, которые содержатся в глоссарии, хранящемся в базе данных. Вот моя выкройка:

/($word)/i

Проблема в том, что если я использую /(Foo)/iтакие слова, как « Foodнайти соответствие». С обеих сторон слова должны быть пробелы или граница слова.

Как я могу изменить свое выражение, чтобы оно соответствовало только слову, Fooесли оно является словом в начале, середине или конце предложения?

Ответы:


126

Используйте границы слов:

/\b($word)\b/i

Или, если вы ищете "SPECTER", как в примере Синан Унюра:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i

1
Когда вы писали, я просто набирал длинную версию этого ответа. :)
ZombieSheep

@RichardSimoes \b(<|>=)\bне совпадает>=
alhelal

@RichardSimoes и \b[-|+][0-9]+\bматч +10в 43E+10. Я не хочу обоих.
alhelal

что, если я хочу найти слово, которое не добавлено или не содержится ни в одном другом слове. тогда эта логика не сработает
Прасанна Сасне

Как получить математические операторы сравнения> = и <=?
AntonSack

52

Чтобы сопоставить любое слово целиком, используйте шаблон (\w+)

Предполагая, что вы используете PCRE или что-то подобное:

введите описание изображения здесь

Выше снимок экрана взят из этого живого примера: http://regex101.com/r/cU5lC2

Соответствие любому целому слову в командной строке с помощью (\w+)

Я буду использовать интерактивную оболочку phpsh в Ubuntu 12.10, чтобы продемонстрировать механизм регулярных выражений PCRE с помощью метода, известного как preg_match.

Запустите phpsh, поместите содержимое в переменную, совпадение по слову.

el@apollo:~/foo$ phpsh

php> $content1 = 'badger'
php> $content2 = '1234'
php> $content3 = '$%^&'

php> echo preg_match('(\w+)', $content1);
1

php> echo preg_match('(\w+)', $content2);
1

php> echo preg_match('(\w+)', $content3);
0

Метод preg_match использовал PCRE двигатель в языке PHP для анализа переменных: $content1, $content2и $content3с (\w)+рисунком.

$ content1 и $ content2 содержат хотя бы одно слово, $ content3 - нет.

Сопоставьте количество буквальных слов в командной строке с (dart|fart)

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(dart|fart)', $gun1);
1

php> echo preg_match('(dart|fart)', $gun2);
1

php> echo preg_match('(dart|fart)', $gun3);
1

php> echo preg_match('(dart|fart)', $gun4);
0

переменные gun1 и gun2 содержат строку dart или fart. gun4 - нет. Однако поиск fartсовпадений слов может быть проблемой farty. Чтобы исправить это, установите границы слов в регулярном выражении.

Сопоставьте буквальные слова в командной строке с границами слов.

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(\bdart\b|\bfart\b)', $gun1);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun2);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun3);
0

php> echo preg_match('(\bdart\b|\bfart\b)', $gun4);
0

Так что же , как и в предыдущем примере , за исключением , что слово fartс \bграницей слова не существует в содержании: farty.


am, pm не слова?
миньон

Если вы хотите, чтобы am и pm были словами (это не так, это аббревиатуры), добавьте точку в качестве символа слова для вашего механизма регулярных выражений. Вам кажется, что вы установили точку не как символ слова, поэтому слова регулярного выражения не будут однозначными для стандартного определения слова, которому вас научили в своем Европейском словаре для вашего гибридного европейского языка. язык (или любой другой язык в этом отношении).
Эрик Лещинский

8

Использование \bможет дать удивительные результаты. Вам будет лучше выяснить, что отделяет слово от его определения, и включить эту информацию в свой шаблон.

#!/usr/bin/perl

use strict; use warnings;

use re 'debug';

my $str = 'S.P.E.C.T.R.E. (Special Executive for Counter-intelligence,
Terrorism, Revenge and Extortion) is a fictional global terrorist
organisation';

my $word = 'S.P.E.C.T.R.E.';

if ( $str =~ /\b(\Q$word\E)\b/ ) {
    print $1, "\n";
}

Вывод:

Компиляция REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Итоговая программа:
   1: СВЯЗАННЫЙ (2)
   2: ОТКРЫТЬ1 (4)
   4: ТОЧНЫЙ (9)
   9: ЗАКРЫТЬ1 (11)
  11: СВЯЗАННЫЙ (12)
  12: КОНЕЦ (0)
привязанный "SPECTER" к 0 (проверка привязки) stclass BOUND minlen 14
Угадание начала совпадения в sv для REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" против "SP
.ECTRE (специальный руководитель контрразведки, "...
Обнаружена привязанная подстрока "SPECTER" со смещением 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Не противоречит СТКЛАССУ ...
Угадано: совпадение по смещению 0
Соответствие REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" с "SPECTER" (Special Exec
агент контрразведки, "...
   0 | 1: СВЯЗАННЫЙ (2)
   0 | 2: ОТКРЫТЬ1 (4)
   0 | 4: ТОЧНЫЙ (9)
  14 | 9: ЗАКРЫТЬ1 (11)
  14 | 11: СВЯЗАННЫЙ (12)
                                  не удалось...
Матч не удался
Освобождение REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"

1
Я думаю, что слово обычно будет словом \ w, но интересный момент.
Ричард Симойс

1

использовать границы слов \ b,

В моей среде работает следующее (с использованием четырех экранирований): Mac, safari Version 10.0.3 (12602.4.8)

var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)

1

Для тех, кто хочет проверить Enum в своем коде, вы можете следовать руководству

В Regex World вы можете использовать как ^для начала строки, так и $для ее завершения. Использование их в сочетании с |может быть тем, что вы хотите:

^(Male)$|^(Female)$

Он вернет true только для случая Maleили Female.


^и $соответствует началу (соответственно концу) строки, поэтому ваш пример будет соответствовать, только если это единственные слова в строке.
gented

и это именно то, что я хочу, когда хочу проверить перечисление! в чем проблема?
MohamadrezaRahimianGolkhandani

0

Если вы делаете это в Notepad ++

[\w]+ 

Дала бы вам слово целиком, и вы можете добавить скобки, чтобы получить его как группу. Пример: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Я хотел бы перейти LeakyReLUв отдельную строку в качестве комментария и заменить текущую активацию. В блокноте ++ это можно сделать с помощью следующей команды find:

([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)

и команда замены становится:

\1\2'relu'\4 \n    # \1 = LeakyReLU\(alpha=a\)\(\1\)

Пробелы предназначены для сохранения правильного форматирования в моем коде. :)


-1

Получить все "слова" в строке

/([^\s]+)/g

В основном ^/sозначает разбиение на пробелы (или сопоставление групп непробелов).
Не забудьте про gGreedy

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.