现在,我正在尝试创建一个脚本,自动创建指向Wiki文档中其他页面的链接。
function createLinks(startingSymbol, endingSymbol, text, links){
//this needs to be implemented somehow - replace every match of the list of links with a link
}
createLinks("[[", "]]", "This is the text to wikify", ["wikify", "text"]);
//this function would return "This is the [[text]] to [[wikify]]" as its output.
最明显的解决方案是简单地用text
替换字符串[[text]]
的每个匹配项,但之后我会遇到一些问题 - 例如,如果我尝试wikify字符串{{ 1}}和"some problems"
在字符串“some some”中,我最终会得到字符串"problems"
。有没有办法解决这个问题?
答案 0 :(得分:1)
我已经创建了一个脚本的工作演示,几乎完全符合我的需要。
alert(wikifyText("[[", "]]", "There are cars, be careful, carefully, and with great care!!", ["text", "hoogahjush", "wikify", "car", "careful", "carefully", "great care"]));
function wikifyText(startString, endString, text, list){
//sort list into ascending order
list.sort(function(a, b){
return a.length - b.length; // ASC -> a - b; DESC -> b - a
});
//replace every element in the array with the wikified text
for(var i = 0; i < list.length; i++){
text = text.replace(list[i], startString + list[i] + endString);
}
return text;
}
谨慎提醒:在某些情况下,此脚本可能会对其他单词中的单词进行说明。例如,如果单词"careful"
不在列表中,并且单词car
在列表中,那么单词"car"
将在单词"careful"
内被取消,像这样:"[[car]]eful"
。我希望我能够解决这个限制。
答案 1 :(得分:1)
这是另一种基于动态构建正则表达式的方法:
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
锚点阻止此版本尝试wikify任何部分单词,但如果您需要,可以放宽此限制。例如,用以下代码替换regexp构造:
var re = new RegExp( '\\b(' + list.join('|') + ')(?=(e?s)?\\b)', 'g' );
会在最后一个wikified字(JSFiddle)的末尾添加s
或es
后缀。请注意,MediaWiki会在显示页面时自动将这些后缀包含在链接文本中。
编辑:这是一个版本,它还允许每个短语的第一个字母不区分大小写,就像MediaWiki页面标题一样。它还使用稍微更友好的解决方案替换\b
锚点:
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 regexps支持标准的PCRE功能,如不区分大小写的部分,后视或Unicode字符类,那么这将不那么混乱。
特别是,由于这些缺失的功能中的最后一个,即使这个解决方案仍然不是完全 Unicode感知的:特别是,它允许链接在匹配任何匹配的字符之前或之后开始{ {1}},包括标点符号,但也包括所有非ASCII字符,甚至是字母。 (但是,正确处理链接内的非ASCII字母。)在实践中,我认为这不应该是一个主要问题。