这是另一种基于动态构建正则表达式的方法:
function wikifyText (startString, endString, text, list) {
list = list.map( function (str) {
return str.replace( /([^a-z0-9_])/g, '\\$1' );
});
list.sort();
list.reverse();
var re = new RegExp( '\\b(' + list.join('|') + ')\\b', 'g' );
return text.replace( re, startString + '$1' + endString );
}
( JSFiddle )
\b
正则表达式两端的锚点可防止此版本尝试对任何部分单词进行维基化,但如果您愿意,可以放宽此限制。例如,将正则表达式构造替换为:
var re = new RegExp( '\\b(' + list.join('|') + ')(?=(e?s)?\\b)', 'g' );
将允许在最后一个维基化单词( JSFiddle)的末尾添加一个s
或后缀。请注意,当显示页面时,MediaWiki 会自动将这些后缀作为链接文本的一部分。es
编辑:这是一个版本,它还允许每个短语的第一个字母不区分大小写,就像 MediaWiki 页面标题一样。它还用对\b
Unicode 更友好的解决方案替换了锚点:
function wikifyText (startString, endString, text, list) {
list = list.map( function (str) {
var first = str.charAt(0);
str = first.toUpperCase() + first.toLowerCase() + str.substr(1);
str = str.replace( /(\W)/ig, '\\$1' );
return str.replace( /^(\\?.\\?.)/, '[$1]' );
});
list.sort();
list.reverse();
var re = new RegExp( '(^|\\W)(' + list.join('|') + ')(?=(e?s)?\\W)', 'g' );
return text.replace( re, '$1' + startString + '$2' + endString );
}
( JSFiddle )
如果 JavaScript 正则表达式支持诸如不区分大小写的部分、后视或 Unicode 字符类之类的标准 PCRE 功能,这将不会那么混乱。
特别是,由于这些缺失的最后一个功能,即使这个解决方案仍然不能完全识别 Unicode:特别是,它允许链接在任何匹配的字符之后开始或结束\W
,其中包括标点符号以及所有非 ASCII 字符,甚至是字母。(但是,链接中的非 ASCII 字母得到了正确处理。)在实践中,我不认为这应该是一个主要问题。