我有一些内容,例如:
如果您有任何疑问,请在StackOverflow上寻求帮助
我有一个同义词列表:
a={one typical|only one|one single|one sole|merely one|just one|one unitary|one small|this solitary|this slight}
ask={question|inquire of|seek information from|put a question to|demand|request|expect|inquire|query|interrogate}
我正在使用JavaScript:
=
{...|...}
输出应如下所示:
如果你有{一个典型|只有一个|一个|一个|仅一个|一个|一个|这个孤零零|这个轻微}的问题,{问题|查询|查询信息来自| put问题|请求|请求|期望|查询|查询|询问}获取有关StackOverflow的帮助
问题:
它不是取代整个单词,而是取代找到的每个字符。我的代码:
for(syn in allSyn) {
var rtnSyn = allSyn[syn].split("=");
var word = rtnSyn[0];
var synonym = (rtnSyn[1]).trim();
if(word && synonym){
var match = new RegExp(word, "ig");
postProcessContent = preProcessContent.replace(match, synonym);
preProcessContent = postProcessContent;
}
}
它应该用同义词替换内容词,而不应该在{...|...}
。
答案 0 :(得分:3)
构建正则表达式时,您需要在开头和结尾都包含word boundary anchors以匹配整个单词(仅以[a-zA-Z0-9_]
开头和结尾):
var match = new RegExp("\\b" + word + "\\b", "ig");
根据您所做的具体替换,您可能希望将方法应用于使用像/\w+/g
这样的正则表达式匹配的单个单词(而不是一次整个文本),以避免替换本身就是替代他人。类似的东西:
content = content.replace(/\w+/g, function(word) {
for(var i = 0, L = allSyn.length; i < L; ++i) {
var rtnSyn = allSyn[syn].split("=");
var synonym = (rtnSyn[1]).trim();
if(synonym && rtnSyn[0].toLowerCase() == word.toLowerCase()) return synonym;
}
});
答案 1 :(得分:1)
正则表达式包含一个称为“单词边界”的东西,由\b
表示。它是一个零宽度断言(它只是检查某些东西,它不会“吃掉”输入),为了匹配,必须应用某些字边界条件。一个例子是一个空格后跟一个字母;给定字符串' X'
,此正则表达式将匹配它:/ \bX/
。因此,为了使您的代码有效,您只需在单词正则表达式的开头和结尾添加单词边界,如下所示:
for(syn in allSyn) {
var rtnSyn = allSyn[syn].split("=");
var word = rtnSyn[0];
var synonym = (rtnSyn[1]).trim();
if(word && synonym){
var match = new RegExp("\\b"+word+"\\b", "ig");
postProcessContent = preProcessContent.replace(match, synonym);
preProcessContent = postProcessContent;
}
}
[请注意,每个单词边界匹配器中都有两个反斜杠,因为在javascript字符串中,反斜杠用于转义字符 - 两个反斜杠变为文字反斜杠。]
答案 2 :(得分:0)
为了优化,不要在每次迭代时创建新的RegExp。相反,构建一个像[^{A-Za-z](a|ask|...)[^}A-Za-z]
这样的大正则表达式,以及一个带有每个键值的散列,指定要替换它的内容。我对JavaScript不熟悉,无法动态创建代码。
请注意,分隔符正则表达式表示匹配不能以{
开头或以}
结尾。这不是非常精确,但希望在实践中可以接受。如果你真的需要替换{
或}
旁边的单词,那么这肯定可以改进,但我希望我们不必这样做。