5

现在,我正在尝试创建一个脚本,该脚本会自动创建指向 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"some problems""problems"在字符串中“一些问题”,我最终会得到字符串"[[some [[problems]]]]"。有没有办法解决这个问题?

4

2 回答 2

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;
}

提醒一句:在某些情况下,此脚本可能会将属于其他单词的单词 wikify。例如,如果该单词"careful"不在列表中,而该单词car在列表中,则该单词"car"将在单词 中被维基化"careful",如下所示:"[[car]]eful". 我希望我能够解决这个限制。

于 2012-12-30T02:16:22.130 回答
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正则表达式两端的锚点可防止此版本尝试对任何部分单词进行维基化,但如果您愿意,可以放宽此限制。例如,将正则表达式构造替换为:

    var re = new RegExp( '\\b(' + list.join('|') + ')(?=(e?s)?\\b)', 'g' );

将允许在最后一个维基化单词( JSFiddle)的末尾添加一个s或后缀。请注意,当显示页面时,MediaWiki 会自动将这些后缀作为链接文本的一部分。es


编辑:这是一个版本,它还允许每个短语的第一个字母不区分大小写,就像 MediaWiki 页面标题一样。它还用对\bUnicode 更友好的解决方案替换了锚点:

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 字母得到了正确处理。)在实践中,我不认为这应该是一个主要问题。

于 2012-12-30T02:38:57.770 回答