在给定页面标题列表的情况下,在MediaWiki页面中自动添加wikilinks

时间:2012-12-30 01:18:20

标签: javascript regex mediawiki

现在,我正在尝试创建一个脚本,自动创建指向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"。有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:1)

我已经创建了一个脚本的工作演示,几乎完全符合我的需要。

http://jsfiddle.net/8JcZC/2/

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)的末尾添加ses后缀。请注意,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字母。)在实践中,我认为这不应该是一个主要问题。