使用JS Regex匹配精确的单词但不是以所述单词开头的带连字符的单词

时间:2013-09-17 18:56:47

标签: javascript regex string

我找不到这个问题的匹配。

我有一个像这样的字符串

var s="one two one-two one-three one one_four"

我的功能如下

 function replaceMatches( str, word )
    {
      var pattern=new RegExp( '\\b('+word+')\\b','g' )
      return str.replace( pattern, '' )
    } 

问题是如果我运行像

这样的功能
var problem=replaceMatches( s,'one' )

returns  two -two -three one_four"

该函数替换每个“one”就像它应该但是用连字符处理单词 在连字符之前用两个单词替换“一”。

我的问题不是关于功能,而是关于正则表达式。文字正则表达式将匹配什么 我的字符串中只有单词“one”而不是“one-two”或“one-\ w”< - 你知道我的意思lol

基本上

var pat=/\b(one)\b/g
"one  one-two one".replace( pat, '')

我希望上面的^返回

" one-two "

只替换完全匹配“one”而不是“one-two”中的匹配 最后的“一”是重要的,如果匹配在最后,正则表达式必须工作 谢谢,对不起,如果我的问题相对混乱。我只是想学习,并扩展我的个人图书馆。

3 个答案:

答案 0 :(得分:1)

你认为什么是一个词?

单词是一个包含1个或多个单词字符的序列,单词边界\b是根据单词字符(和非单词字符)的定义定义的。

JavaScript RegExp中\w定义的单词字符是字符类[a-zA-Z0-9_]的简写。

您对“字”的定义是什么?假设您的定义是[a-zA-Z0-9_-]

模拟单词边界

This post描述了如何在支持look-behind和look-ahead的语言中模拟单词边界。太糟糕了,JS不支持后视。

为简单起见,我们假设要替换的单词是one

我们可以使用以下代码限制替换:

inputString.replace(/([^a-zA-Z0-9_-]|^)one(?![a-zA-Z0-9_-])/g, "$1")

注意:我使用展开的表单[a-zA-Z0-9_-]代替[\w-],以避免与\w关联。

打破正则表达式:

(
  [^a-zA-Z0-9_-]  # Negated character class of "word" character
  |               # OR
  ^               # Beginning of string
)
one               # Keyword
(?!               # Negative look-ahead
  [a-zA-Z0-9_-]   # Word character
)

我通过匹配“word”字符的否定字符类和(?<![a-zA-Z0-9_-])字符串开头的字符来模拟负面的look-behind(如果支持,则为^)。这很自然,因为如果我们找不到“单词”字符,那么它必须是非“单词”字符或字符串的开头。所有东西都包裹在一个捕获组中,以便以后可以替换它。

由于one仅在前后没有“单词”字符时被替换,因此不存在错过匹配的风险。

放在一起

由于您要删除“字词”,因此您必须确保您的关键字仅包含“字”字符。

function replaceMatches(str, keyword)
{
    // The keyword must not contain non-"word" characters
    if (!/^[a-zA-Z0-9_-]+$/.test(keyword)) {
        throw "not a word";
    }

    // Customize [a-zA-Z0-9_-] and [^a-zA-Z0-9_-] with your definition of
    // "word" character
    var pattern = new RegExp('([^a-zA-Z0-9_-]|^)' + keyword + '(?![a-zA-Z0-9_-])', 'g')
    return str.replace(pattern, '$1')
}

如果“单词”字符的定义包含正则表达式元字符,则需要转义关键字中的元字符。

答案 1 :(得分:0)

将此用于RegExp:

function replaceMatches( str, word ) {
  var pattern = new RegExp('(^|[^-])\\b('+word+')\\b([^-]|$)', 'g');
  return str.replace(pattern, '$1$3')
} 

(^|[^-])将匹配字符串的开头或除-之外的任何字符。 ([^-]|$)将匹配-以外的字符或字符串的结尾。

答案 2 :(得分:0)

我不是JS模式函数专家,但函数应该替换所有。

至于one-之间的“一二”中的连字符是一个单词边界(即。\ b)和
如果在它之前有\ w字符,则字符串结尾是一个单词边界。

但是,听起来你可能想要'一个'前面有一个空格或BOL ([ ]|^)one\b在这种情况下,您希望将替换捕获组1设置为1,从而只扫描'one'。

并且,我不确定该函数调用在JS中是如何工作的。

编辑:在新的预期输出之后,正则表达式可以是 -

([ ]|^)one(?=[ ]|$)