0

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

我有一个这样的字符串

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”而不是“one-two”或“one-\w”<--你知道我的意思哈哈

基本上

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

我想要上面的^返回

" one-two "

只替换完全匹配的“一”而不是“一二”中的一令人困惑。我只是想继续学习,并扩大我的个人图书馆。

4

3 回答 3

1

你认为什么是一个词?

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

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

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

模拟单词边界

这篇文章描述了如何在支持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
)

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

由于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')
}

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

于 2013-09-17T19:30:47.837 回答
0

将此用于您的正则表达式:

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

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

于 2013-09-17T19:02:15.563 回答
0

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

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

但是,听起来您可能希望“one”前面带有空格或 BOL。
([ ]|^)one\b在这种情况下,您希望将替换捕获组设为 1,从而仅去除“一个”。

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

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

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

于 2013-09-17T19:21:41.033 回答