替换数据块中的多个模式

时间:2010-03-23 15:56:35

标签: javascript regex algorithm

我需要找到在单个文本块上匹配多个正则表达式的最有效方法。举一个我需要的例子,考虑一个文本块:

“Hello World多么美好的一天”

我想用Universe替换Hello与“Bye”和“World”。我总是可以在一个循环的循环中使用像各种语言中可用的String.replace函数这样的东西。

但是,我可能有一个包含多个字符串模式的大块文本,我需要匹配和替换。

我想知道我是否可以使用正则表达式来有效地执行此操作,或者我是否必须使用像LALR这样的解析器。

我需要在JavaScript中执行此操作,因此如果有人知道可以完成它的工具,那将不胜感激。

5 个答案:

答案 0 :(得分:11)

修改

在我原来的答案(下面)6年后,我会以不同的方式解决这个问题

function mreplace (replacements, str) {
  let result = str;
  for (let [x, y] of replacements)
    result = result.replace(x, y);
  return result;
}

let input = 'Hello World what a beautiful day';

let output = mreplace ([
  [/Hello/, 'Bye'],
  [/World/, 'Universe']
], input);

console.log(output);
// "Bye Universe what a beautiful day"

这比之前的答案有很大的优势,它要求你每次写两次比赛。它还可以让您个人控制每场比赛。例如:

function mreplace (replacements, str) {
  let result = str;
  for (let [x, y] of replacements)
    result = result.replace(x, y);
  return result;
}

let input = 'Hello World what a beautiful day';

let output = mreplace ([
  //replace static strings
  ['day', 'night'],
  // use regexp and flags where you want them: replace all vowels with nothing
  [/[aeiou]/g, ''],
  // use captures and callbacks! replace first capital letter with lowercase 
  [/([A-Z])/, $0 => $0.toLowerCase()]

], input);

console.log(output);
// "hll Wrld wht  btfl nght"


原始答案

可以修改

Andy E的答案,以便更轻松地添加替换定义。

var text = "Hello World what a beautiful day";
text.replace(/(Hello|World)/g, function ($0){
  var index = {
    'Hello': 'Bye',
    'World': 'Universe'
  };
  return index[$0] != undefined ? index[$0] : $0;
});

// "Bye Universe what a beautiful day";

答案 1 :(得分:9)

您可以传递一个替换函数:

var hello = "Hello World what a beautiful day";
hello.replace(/Hello|World/g, function ($0, $1, $2) // $3, $4... $n for captures
{
    if ($0 == "Hello")
        return "Bye";
    else if ($0 == "World")
        return "Universe";
});

// Output: "Bye Universe what a beautiful day";

答案 2 :(得分:1)

改进的答案:

var index = {
    'Hello': 'Bye',
    'World': 'Universe'
};

var pattern = '';
for (var i in index) {
    if (pattern != '') pattern += '|';
    pattern += i;
}

var text = "Hello World what a beautiful day";
text.replace(new RegExp(pattern, 'g'), function($0) {
    return index[$0] != undefined ? index[$0] : $0;
});

答案 3 :(得分:0)

如果问题是如何用相应的替换物(stringsfunctions替换多个通用模式,则由于特殊字符,捕获组和反向引用匹配而非常棘手

您可以为此目的使用https://www.npmjs.com/package/union-replacer。它基本上是string.replace(regexp, string|function)的对应对象,它允许一次替换执行多次替换,同时保留string.replace(...)的全部功能。

披露:我是作者,开发该库是因为我们必须支持用户配置的替换。

答案 4 :(得分:0)

一个涉及替换多个模式的常见任务是使用户或其他字符串在网页上呈现“安全”,这意味着阻止 HTML 标记处于活动状态。这可以在 JavaScript 中使用 HTML 实体和 forEach 函数完成,允许一组异常(即允许呈现的一组 HTML 标记)。

这是一项常见任务,以下是完成它的相当简单的方法:

// Make a string safe for rendering or storing on a Web page
function SafeHTML(str)
    {
    // Make all HTML tags safe
    let s=str.replace(/</gi,'&lt;');

    // Allow certain safe tags to be rendered
    ['br','strong'].forEach(item=>
        {
        let p=new RegExp('&lt;(/?)'+item+'>','gi');
        s=s.replace(p,'<$1'+item+'>');
        });
    return s;
    } // SafeHTML