我有一个正则表达式,可以匹配单词,但如果单词包含特殊字符,比如C++类成员的名称~Query,则无法匹配成功。需要像下面一样使用单词边界来匹配单个字符的成员名:
$key =~ /\b$match\b/
我尝试了许多我认为会起作用的表达式,比如/[~]*\b$match\b/
或 /\b[~]*$match\b/
是否可能在可能包含特殊字符的单词上放置单词边界?
\b
是...的缩写
(?:(?<!\w)(?=\w)|(?<=\w)(?!\w))
如果您想将 ~
视为单词字符,请将 \w
改为 [\w~]
。(?:(?<![\w~])(?=[\w~])|(?<=[\w~])(?![\w~]))
使用示例:
my $word_char = qr/[\w~]/;
my $boundary = qr/(?<!$word_char)(?=$word_char)
|(?<=$word_char)(?!$word_char)/x;
$key =~ /$boundary$match$boundary/
如果我们知道$match
只能匹配以$word_char
开头和结尾的内容,那么我们可以简化为以下步骤:
my $word_char = qr/[\w~]/;
my $start_bound = qr/(?<!$word_char)/;
my $end_bound = qr/(?!$word_char)/;
$key =~ /$start_bound$match$end_bound/
这个简单到我们可以内联它。
$key =~ /(?<![\w~])$match(?![\w~])/
(?:^|[^\w~])([\w~]+)(?![\w~])
的东西并提取第一个捕获组。但是你不再匹配边界本身,因此它有一些限制(例如,在更大的模式中使用起来更困难)。 - ikegami假设您不需要检查$match
的内容(即它总是包含有效的标识符),您可以编写以下代码:
$key =~ /(?<![~\w])$match(?![~\w])/
这个函数只是简单地检查$match
字符串的前后是否跟字母数字、下划线或波浪号相邻。
$match
中包含的正则表达式可以匹配Query
,那么/~\b$match\b/
应该匹配~Query
。(我刚刚测试过," ~foo " =~ /~\bfoo\b/
的结果为真。) - cdhowieQuery、Query或单个字母,比如p。开发人员可能会为他们的类方法使用其他奇怪的名称。正则表达式是一个执行搜索的子程序的一部分。除了当$match包含Query时,一切都运行正常。 - Jeff Cunningham