【问题标题】:Regex expression using word boundary for matching alphanumeric and non alphanumeric characters in javascript使用单词边界的正则表达式来匹配 javascript 中的字母数字和非字母数字字符
【发布时间】:2011-05-12 01:21:35
【问题描述】:

我正在尝试使用 JavaScript 和正则表达式突出显示一组关键字,我遇到了一个问题,我的关键字可能包含文字和特殊字符,如 @text #number 等。我正在使用单词边界来匹配和替换整个单词而不是部分单词(包含在另一个单词中)。

var pattern = new regex('\b '( + keyword +')\b',gi);

这里这个表达式匹配整个关键字并突出显示它们,但是如果像“数字:”这样的关键字没有被突出显示。

我知道\bword\b 匹配单词边界,特殊字符是非字母数字字符,因此与上述表达式不匹配。 你能告诉我我可以使用什么正则表达式来完成上述操作。

==更新==

对于上述内容,我尝试了 Tim Pietzcker 对以下正则表达式的建议,

expr: (?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)

上面的内容似乎可以让我使用字母数字和非字母数字字符匹配整个单词,但是只要关键字在关键字之前或之后有连续的 html 标记而没有空格,它就不会突出显示该关键字(例如社会保障*号码:*) 我尝试了以下正则表达式,但它替换了关键字

之前的 html 标记
expr: (?:^|\b|\s|<[^>]+>)number:(?:$|\b|\s|<[^>]+>) 

这里的关键字 number: 具有 &lt; br &gt;(为 br 标签故意添加空格以避免浏览器解释标签)接下来没有空格,关键字会突出显示。

你能建议一个表达式,它会忽略整个单词的连续 html 标记,同时包含字母数字和非字母数字字符。

【问题讨论】:

标签: javascript regex alphanumeric


【解决方案1】:

2021 年更新:JS 现在支持lookbehind,所以这个答案有点过时了。

好的,所以你有两个问题:JavaScript 不支持后视,\b 只能找到字母数字和非字母数字字符之间的界限。

第一个问题: 究竟是什么构成了您的关键字的词边界?我的猜测是它必须是\b 边界或空格。如果是这种情况,您可以搜索

"(?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)"

当然,像@number# 这样的关键字周围的空白字符也会成为匹配的一部分,但也许突出显示这些不是问题。在其他情况下,我。 e.如果存在可以匹配的实际单词边界,则空格不会成为匹配的一部分,因此在大多数情况下应该可以正常工作。

您感兴趣的实际单词将在反向引用 #1 中,因此如果您可以单独突出显示它,那就更好了。

编辑: 如果在关键字之后/之前可能出现除空格之外的其他字符,那么我认为您唯一能做的(如果您被 JavaScript 卡住)是:

  1. 检查您的关键字是否以 alnum 字符开头。
  2. 如果是这样,请将 \b 添加到您的正则表达式中。
  3. 检查您的关键字是否以 alnum 字符结尾。
  4. 如果是这样,请将\b 附加到您的正则表达式中。

所以,对于keyword,使用\bkeyword\b;对于number:,使用\bnumber:;对于@twitter,使用@twitter\b

【讨论】:

  • 上述内容似乎可以让我使用字母数字和非字母数字字符匹配整个单词,但是只要关键字在关键字之前或之后有连续的 html 标签,它就不会突出显示该关键字(例如社会安全号码:
    )。你能告诉我如何忽略那些html标签(可能是任何标签)我尝试了以下正则表达式,但它替换了关键字之前的html标签
  • expr: (?:^|\b|\s|]+>)number:(?:$|\b|\s|]+>)
【解决方案2】:

我们需要寻找一个两边都有空格的子字符串。如果 JavaScript 支持后视,则如下所示:

var re = new RegExp('(?<!\\S)' + keyword + '(?!\\S)', 'gi');

虽然这行不通(但在 Perl 和其他脚本语言中可以)。相反,我们需要包含前导空白字符(或字符串的开头)作为匹配的开始部分(并且可以选择将我们真正要查找的内容捕获到 $1 中):

var re = new RegExp('(?:^|\\s)(' + keyword + ')(?!\\S)', 'gi');

只需考虑任何匹配开始的真实位置将是一个字符re.exec(string)返回的.index属性返回的内容,并且如果您正在访问匹配的字符串,您要么需要使用.slice(1) 删除第一个字符,要么只需访问捕获的内容。

【讨论】:

    【解决方案3】:

    也许你想做的是

    '\b\W*(' + keyword + ')\W*\b'
    

    【讨论】:

      【解决方案4】:

      前瞻和后瞻是您的答案:"(?=&lt;[\s^])" + keyword + "(?=[\s$])"。括号中的位不包含在匹配项中,因此请包含其中关键字中不允许使用的任何字符。

      【讨论】:

      • 糟糕,我的错误... JavaScript 不支持后向查看(尽管出于某种原因它确实支持前向查看)。忽略。
      【解决方案5】:

      正如蒂姆正确指出的那样,\b 是一些棘手的事情,其工作方式与人们通常认为的工作方式不同。阅读this answer 了解有关此问题的更多详细信息以及您可以采取的措施。

      简而言之,这是向左的边界:

      (?(?=\w)(?<!\w)|(?<!\W))
      

      这是右边的边界:

      (?(?<=\w)(?!\w)|(?!\W))
      

      人们总是认为存在空间,但实际上并非如此。但是,既然您知道了真正的定义,就很容易将其构建到它们中。可以将\w\W 替换为上述两种模式中的\s\S。或者可以将空格意识添加到 else 块中。

      【讨论】:

        【解决方案6】:

        试试这个应该可以的...

        var pattern = new regex(@"\b"+Regex.escape(keyword)+@"\b",gi);
        

        【讨论】:

          猜你喜欢
          • 2017-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-01
          • 2013-04-17
          • 1970-01-01
          相关资源
          最近更新 更多