2010-03-23 26 views
6

我需要找到在单个文本块上匹配多个正则表达式的最有效方法。为了给什么,我需要一个例子,考虑文本块:替换数据块中的多个模式

的“Hello World美好的一天是什么”

我想用“再见”和“世界”与宇宙更换你好。我总是可以在一个循环的课程中使用像String.replace函数一样在各种语言中使用。

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

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

我需要在JavaScript中做到这一点,所以如果有人知道可以完成它的工具,将不胜感激。

回答

6

你可以通过一个函数来代替:

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"; 
+0

刚一说明,安迪E:你需要一个')'之前,你的';'最后一行:) – 2010-03-23 17:30:39

+0

@smotchkkiss:是的,我注意到,因为我在底部输入评论,并在完成时完全忘记!谢谢:-) – 2010-03-23 23:42:10

+0

谢谢,这真的很有帮助。然而,是正则表达式匹配限制为1美元或9美元,或者我们也可以有10美元,11美元等... – VikrantY 2010-03-24 07:59:09

10

编辑我原来的答复(见下文)

后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"; 
+0

感谢Andy/smotchkiss你们都完全整理了我的问题,避免了我不得不编写自己的算法,进行多次更换。 – VikrantY 2010-03-24 13:57:10

+2

也许你不应该为每次调用替换函数重新创建查找对象,对吧,但是它可以在外面使用吗? – Phrogz 2010-12-08 03:38:24

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; 
}); 
+0

这是一个旧的问题与旧的答案。我认为你提供了一个很好的改进,但是你可以通过'RegExp'构造函数和自动附加'g'标志来强制输入,从而扩大用户的权力。 – 2016-12-06 17:46:40