2016-07-14 9 views
0

JavaScriptでPHP構文ハイライトのコードを書いています。JavaScript - グローバル修飾子が正しく機能しない

<html> 
 

 
<head> 
 

 
    <title>Untitled 1</title> 
 

 
<script> 
 
function showContents(text) { 
 
    var string = /\"[[email protected]#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*\"/i; 
 
    var aVariable = /\$([a-zA-Z0-9_\x7f-\xff]*)/i; 
 
    var output = text; 
 
    if(aVariable.test(output)==true) 
 
    { 
 
     output = output.replace(aVariable.exec(output)[0],"<font color='blue'>"+aVariable.exec(output)[0]+"</font>"); 
 
     document.getElementById("UserInput").innerHTML = output; 
 
    } 
 
    if(string.test(output)==true) 
 
    { 
 
     output = output.replace(string.exec(output)[0],"<font color='red'>"+string.exec(output)[0]+"</font>"); 
 
     document.getElementById("UserInput").innerHTML = output; 
 
    } 
 
    else 
 
    { 
 
     document.getElementById("UserInput").innerHTML = output; 
 
    } 
 
    document.write(output); 
 
} 
 
</script> 
 
</head> 
 

 
<body> 
 
<div id="UserInput"></div> 
 
<form> 
 
<textarea onkeyup="showContents(this.value)"></textarea></form> 
 

 
</body> 
 
</html>

は、上記のスクリプトは次のように入力するために正常に動作します:

$name="ABC" 

しかし、私のような入力しようとした場合:

$name="ABC";$name2="CDE" 
をここに私がしようとしたものです

コードは最初のインスタンス(つまり、$name="ABC")。修飾子をグローバルに変更しても、出力自体は提供されません。

+0

最初に置換すると、プレーンテキスト文字列ではなくHTML文字列が使用されます。そして、それは[これを解析するために正規表現を使うことはもはや不可能です](http://stackoverflow.com/a/1732454/1529630)。正規表現ではなく適切なパーサーが必要です。 – Oriol

答えて

0

aVariable.exec(output)[0]を使用すると、最初の一致が返され、置換する方法がreplaceに渡されるという問題があります。このコードは1回だけ実行されるため、2回目の一致は決して処理されません。

正規表現をreplaceに直接渡し、exec(これは文字列の配列)の結果ではありません。また、replaceにコールバック関数を渡すことができるので、各一致でコードを実行してfontタグをラップすることができます。ここで

が働いスニペットです:正1文字以内のネガティブリストを渡すことが容易であるよう

function htmlEncode(text) { 
 
    // Uses the DOM to correctly escape HTML special characters (e.g. ampersand, less-than) 
 
    var elm = document.createElement('span'); 
 
    elm.textContent = text; 
 
    return elm.innerHTML; 
 
} 
 

 
function formatContents(text) { 
 
    // Use one regexp for all, and modify the matches with a call back function: 
 
    return text.replace(/(\"(\\"|.)*?\")|(\$([\w\x7f-\xff]*))/g, function (match, str, vari) { 
 
     var color = str ? 'red' : 'blue'; 
 
     return "<font color='" + color + "'>" + htmlEncode(match) + "</font>"; 
 
    }); 
 
} 
 

 
function showContents() { 
 
    // Take contents from textarea and display formatted in UserInput div: 
 
    document.getElementById("UserInput").innerHTML = 
 
     formatContents(document.getElementById("input").value); 
 
} 
 

 
document.getElementById("input").oninput = showContents; 
 
// Apply upon page load 
 
showContents();
The formatting is done as you type:<br> 
 
<textarea id="input" style="width:100%">$name="ABC"; 
 
$name2="CDE"</textarea> 
 
<div id="UserInput" style="white-space: pre"></div>

私は、正規表現を少し「文字列」に変更しました。

正規表現で置き換えを行う利点は、一度一致すると、その部分文字列が他のものと再びマッチしないことです(変数は決して文字列リテラルではなく、逆も同様です)。

関連する問題