【发布时间】:2017-07-08 19:21:10
【问题描述】:
我有一个正则表达式,用于查找给定内容块中的所有单词,不区分大小写,这些单词包含在存储在数据库中的词汇表中。这是我的模式:
/($word)/i
问题是,如果我使用/(Foo)/i,那么像Food 这样的词就会匹配。单词两边必须有空格或单词边界。
当 Foo 是句子开头、中间或结尾的单词时,如何修改我的表达式以仅匹配单词?
【问题讨论】:
标签: regex word-boundary
我有一个正则表达式,用于查找给定内容块中的所有单词,不区分大小写,这些单词包含在存储在数据库中的词汇表中。这是我的模式:
/($word)/i
问题是,如果我使用/(Foo)/i,那么像Food 这样的词就会匹配。单词两边必须有空格或单词边界。
当 Foo 是句子开头、中间或结尾的单词时,如何修改我的表达式以仅匹配单词?
【问题讨论】:
标签: regex word-boundary
使用单词边界:
/\b($word)\b/i
或者,如果您正在搜索“S.P.E.C.T.R.E.”就像 Sinan Ünür 的例子:
/(?:\W|^)(\Q$word\E)(?:\W|$)/i
【讨论】:
\b(<|>=)\b 不匹配 >=
\b[-|+][0-9]+\b 匹配 +10 中的 43E+10。两个我都不想要。
(\w+)
假设您使用的是 PCRE 或类似的东西:
以上截图来自这个现场示例:http://regex101.com/r/cU5lC2
(\w+) 匹配
我将在Ubuntu 12.10 上使用phpsh interactive shell 通过称为preg_match 的方法演示PCRE regex engine
启动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 方法使用 PHP 语言中的 PCRE 引擎来分析变量:$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
所以它与前面的示例相同,只是内容中不存在带有\b 字边界的单词fart: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";
}
输出:
编译 REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" 最终程序: 1:绑定 (2) 2:打开 1 (4) 4:准确(9) 9:关闭 1 (11) 11:绑定 (12) 12:结束(0) 锚定“S.P.E.C.T.R.E.”在 0(检查锚定) stclass BOUND minlen 14 在 sv 中猜测 REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" 对 "S.P" 的匹配开始 .E.C.T.R.E. (反情报特别执行官,... 找到锚定的 substr "S.P.E.C.T.R.E."在偏移量 0... start_shift: 0 check_at: 0 s: 0 endpos: 1 与STCLASS不矛盾... 猜测:在偏移量 0 处匹配 匹配 REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" 与 "S.P.E.C.T.R.E. (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"【讨论】:
如果你是在记事本++中做的
[\w]+
会给你整个单词,你可以添加括号将它作为一个组来获取。示例:conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs)。我想将LeakyReLU 作为注释移到它自己的行中,并替换当前的激活。在记事本++中,这可以使用以下查找命令来完成:
([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)
替换命令变为:
\1\2'relu'\4 \n # \1 = LeakyReLU\(alpha=a\)\(\1\)
空格是为了在我的代码中保持正确的格式。 :)
【讨论】:
对于那些想要在他们的代码中验证枚举的人,您可以按照指南进行操作
在 Regex World 中,您可以使用 ^ 开始一个字符串并使用 $ 结束它。将它们与| 结合使用可能是您想要的:
^(Male)$|^(Female)$
它只会在Male 或Female 的情况下返回true。
【讨论】:
^ 和 $ 匹配一行的开头(分别是结尾),因此如果这些是该行中唯一的单词,您的示例将匹配 only。
使用单词边界\b,
以下(使用四个转义)适用于我的环境:Mac、Safari 版本 10.0.3 (12602.4.8)
var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)
【讨论】:
获取字符串中的所有“单词”
/([^\s]+)/g
基本上
^/s表示空格(或匹配非空格组)
不要忘记贪婪的g
【讨论】: