正则表达式匹配以特殊字符开头的单词边界

11

我有一个正则表达式,可以匹配单词,但如果单词包含特殊字符,比如C++类成员的名称~Query,则无法匹配成功。需要像下面一样使用单词边界来匹配单个字符的成员名:

$key =~ /\b$match\b/

我尝试了许多我认为会起作用的表达式,比如/[~]*\b$match\b//\b[~]*$match\b/

是否可能在可能包含特殊字符的单词上放置单词边界?


1
你能准确地发布你想匹配的内容吗?正则表达式是针对具体情况生成的,而不是仅仅假设了你的字符串。 - Rohit Jain
1
假设在 $match 中包含的正则表达式可以匹配 Query,那么 /~\b$match\b/ 应该匹配 ~Query。(我刚刚测试过," ~foo " =~ /~\bfoo\b/ 的结果为真。) - cdhowie
$match变量可能包含Query、Query或单个字母,比如p。开发人员可能会为他们的类方法使用其他奇怪的名称。正则表达式是一个执行搜索的子程序的一部分。除了当$match包含Query时,一切都运行正常。 - Jeff Cunningham
2个回答

18
\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~])/

谢谢,这正是我想要的,尽管有点冗长。 $key =~ /(?:(?<=[\w])(?![\w])|(?<![\w])(?=[\w]))$match(?:(?<=[\w])(?![\w])|(?<![\w])(?=[\w]))/) - Jeff Cunningham
1
如果我需要包含其他特殊字符,它们会像这样添加 [\w~`] 吗? - Jeff Cunningham
相同的 \b 扩展适用于 C#,并且替换 \w 也像魔术一样奏效。 - drizin
Firefox不支持后顾之前,有没有解决方法? - adam0101
@ikegami,抱歉,是JavaScript。我正在从文本中提取多个编程语言名称(C#,C ++)。您移植到JS的代码非常出色,除了不支持后顾的浏览器 :) - adam0101
@adam0101,你可以使用类似 (?:^|[^\w~])([\w~]+)(?![\w~]) 的东西并提取第一个捕获组。但是你不再匹配边界本身,因此它有一些限制(例如,在更大的模式中使用起来更困难)。 - ikegami

4

假设您不需要检查$match的内容(即它总是包含有效的标识符),您可以编写以下代码:

$key =~ /(?<![~\w])$match(?![~\w])/

这个函数只是简单地检查$match字符串的前后是否跟字母数字、下划线或波浪号相邻。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接