Регулярное выражение соответствует только целым словам
-
20-09-2019 - |
Вопрос
У меня есть регулярное выражение, которое я использую для поиска всех слов в данном блоке содержимого без учета регистра, которые содержатся в глоссарии, хранящемся в базе данных.Вот мой шаблон:
/($word)/i
Проблема в том, что если я использую /(Foo)/i
затем такие слова , как Food
подберите себе пару.С обеих сторон слова должен быть пробел или граница слова.
Как я могу изменить свое выражение, чтобы оно соответствовало только слову Foo
когда это слово находится в начале, середине или конце предложения?
Решение
Используйте границы слов:
/\b($word)\b/i
Или, если вы ищете "S.P.E.C.T.R.E.", как в примере Синана Юнюра:
/(?:\W|^)(\Q$word\E)(?:\W|$)/i
Другие советы
Чтобы сопоставить любое целое слово, вы бы использовали шаблон (\w+)
Предполагая, что вы используете PCRE или что-то подобное:
Приведенный выше скриншот, взятый из этого живого примера: http://regex101.com/r/cU5lC2
Сопоставление любого целого слова в командной строке с (\w+)
Я буду использовать интерактивная оболочка phpsh на Ubuntu 12.10 чтобы продемонстрировать Механизм регулярных выражений PCRE с помощью метода, известного как прег_матч
Запустите phpsh, поместите некоторое содержимое в переменную, сопоставьте в word.
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 этого не делает.Однако может возникнуть проблема в том, что поиск word 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
.
Используя \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";
}
Выходной сигнал:
Compiling REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" Final program: 1: BOUND (2) 2: OPEN1 (4) 4: EXACT (9) 9: CLOSE1 (11) 11: BOUND (12) 12: END (0) anchored "S.P.E.C.T.R.E." at 0 (checking anchored) stclass BOUND minlen 14 Guessing start of match in sv for REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P .E.C.T.R.E. (Special Executive for Counter-intelligence,"... Found anchored substr "S.P.E.C.T.R.E." at offset 0... start_shift: 0 check_at: 0 s: 0 endpos: 1 Does not contradict STCLASS... Guessed: match at offset 0 Matching REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P.E.C.T.R.E. (Special Exec utive for Counter-intelligence,"... 0 | 1:BOUND(2) 0 | 2:OPEN1(4) 0 | 4:EXACT (9) 14 | 9:CLOSE1(11) 14 | 11:BOUND(12) failed... Match failed Freeing REx: "\b(S\.P\.E\.C\.T\.R\.E\.)\b"
используйте границы слова \b,
Следующее (с использованием четырех экранирований) работает в моей среде:Mac, safari версии 10.0.3 (12602.4.8)
var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)
Если вы делаете это в Notepad ++
[\w]+
Это дало бы вам слово целиком, и вы можете добавить круглые скобки, чтобы получить его в виде группы.Пример: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs)
.Я бы хотел переехать LeakyReLU
в свою собственную строку в качестве комментария и замените текущую активацию.В notepad ++ это можно сделать с помощью следующей команды find:
([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)
и команда replace становится:
\1\2'relu'\4 \n # \1 = LeakyReLU\(alpha=a\)\(\1\)
Пробелы предназначены для сохранения правильного форматирования в моем коде.:)