2012-12-30 6 views
5

今、私はwikiドキュメントの他のページへのリンクを自動的に作成するスクリプトを作成しようとしています。私は文字列内の文字列"some problems""problems"をwikifyしようとした場合、例えば -ページタイトルのリストを指定して、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のすべての試合を交換するだろうが、その後私はいくつかの問題に実行するだろう"いくつかの問題"、私は文字列"[[some [[problems]]]]"で終わるだろう。この問題を回避する方法はありますか?

+0

私は本質的に、他の2つの文字列の間にない場合に限り、別の文字列内の文字列を置き換えることができるかどうかを尋ねています。 (例えば、 'str2'が文字列' str3'と 'str4'の間にない場合にのみ、文字列' str2'の中の文字列 'str1'を置き換えます)。 –

+0

これは ''この関数が返すはずです 'これは[出力]として[[テキスト]]から[[wikify]]になりますか? – kieran

+0

Javascriptの正規表現でlookahead演算子とlookbehind演算子を使用してこれを行うことは可能かもしれませんが、私は正規表現の構文に慣れていません。 –

答えて

1

ここでは、動的正規表現を構築する上でベースの別のアプローチは、です:正規表現の両端の\bアンカーは任意の単語の一部をwikifyしようとしているから、このバージョンを防ぐ

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

が、あなたが望むなら、この制限を緩和することができます。最後wikifiedワード(JSFiddle)の終わりにs又はesサフィックスを可能にする

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

たとえば、正規表現を用いて構成を置き換えます。 MediaWikiは、ページが表示されたときにリンクテキストの一部として自動的にそのような接尾辞を含むことに注意してください。


編集:ここではMediaWikiのページタイトルがあるようにも、各フレーズの最初の文字は大文字と小文字を区別しないことを可能にするバージョンがあります。また、多少のUnicodeフレンドリーなソリューションと\bアンカーを置き換えます

JavaScriptは大文字と小文字を区別しないセクションなどの標準的なPCREの機能をサポートする正規表現場合、これははるかに少ない乱雑になり

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)、ルック・バックまたはUnicode文字クラス。特に

、これらの欠けている機能の最後に、でも、この解決策はまだ完全 Unicode対応でないため:特に、それはリンクが後に開始または句読点が含まれて\Wに一致する任意の文字、前に終了することができますすべてのASCII以外の文字、さらには文字も含まれます。 (しかし、ASCII以外の文字内のリンクは正しく処理されます)。実際には、これは大きな問題ではないと私は考えています。

+0

私はスクリプトの私のバージョンを使用してTomboy Notesのクローンを作成しました。入力時にWikipediaへのリンクが生成され、生成されたHTMLも印刷されます。 http://jsfiddle.net/gjqWy/77/ –

+1

@AndersonGreen:Cool!私はあなたに2番目の+1を与えることを望みます。 –

+0

私は同じコードの多くを使ってwikiリンクジェネレータも書いています。 HTMLリンクの代わりにwikiマークアップリンクを生成します。現在のところ、プレーンテキストを適切に偽装することしかできません。 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がリストに含まれている場合は、のように、単語が単語"careful"の中にウィキングされます。私はこの制限を回避することができることを願っています。

関連する問題