2012-12-30 27 views
5

現在,我試圖創建一個腳本,該腳本可以自動創建指向wiki文檔中其他頁面的鏈接。在MediaWiki頁面中自動添加wikilinks,給定頁面標題列表

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]]]]"結束。有什麼辦法可以解決這個問題嗎?

+0

我基本上問是否可以替換另一個字符串中的字符串,當且僅當它不在兩個其他字符串之間時。 (例如,當且僅當'str2'不在字符串'str3'和'str4'之間時,替換字符串'str2'內的字符串'str1')。 –

+0

應該讀取'//此函數將返回「這是[[文本]] [[wikify]]」作爲其輸出「? – kieran

+0

在Javascript正則表達式中使用lookahead和lookbehind操作符可能會這樣做,但我對正則表達式語法不是很熟悉。 –

回答

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任何部分單詞,但如果你想要的話,你可以放鬆這個限制。例如,對於正則表達式替換結構:

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

將允許在最後wikified字(JSFiddle)的端部的ses後綴。請注意,當頁面顯示時,MediaWiki會自動包含這些後綴作爲鏈接文本的一部分。


編輯:這裏有一個版本,也允許每個詞的第一個字母是區分大小寫的,比如鏈接到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的正則表達式支持這樣的標準PCRE特點不區分大小寫的部分這將是少了很多凌亂,後面還是Unicode字符類。

特別是,由於過去的這些缺失的功能,即使這個解決方案仍然沒有完全支持Unicode的:尤其是,它允許鏈接後開始或匹配\W任何字符,包括標點符號之前結束還包括所有非ASCII字符,甚至字母。 (但是,裏面的非ASCII字母鏈接處理正確。)實際上,我認爲這不應該是一個主要問題。

+0

我使用我的腳本版本創建了Tomboy Notes的克隆。它會在您鍵入時生成指向Wikipedia的鏈接,並且還會打印生成的HTML。 http://jsfiddle.net/gjqWy/77/ –

+1

@AndersonGreen:酷!希望我能給你第二個+1。 –

+0

我也寫了一個維基鏈接生成器,使用大部分相同的代碼。它生成維基標記鏈接而不是HTML鏈接。目前,它只能正確地顯示純文本。 http://jsfiddle.net/jarble/gjqWy/78/ –

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"。我希望我能夠解決這個限制。

相關問題