2013-06-24 33 views
1

目前我有一個可編輯div,我想添加非常基本的語法突出顯示。基本上我希望*之間的文字可以用不同的顏色和引號中的文字來轉換不同的顏色。例如:使用javascript的簡單語法突出顯示

輸入:"hello" *world*

輸出:<span class='a'>"hello"</span> <span class='b'>*world*</span>

我使用Rangy.js庫來保存和恢復插入位置,所以沒有問題存在。不過,我真的很努力地把輸入變成輸出。最大的問題我已經被忽略任何「和*那些已經凸顯。

如果任何人都可以在基本算法或正則表達式或東西這將是大加讚賞的方向指向我。

回答

1
function highlight(text) { 
    var result = []; 
    for (var i = 0; i < text.length; i++) { 
     if (text[i] === '"') { 
      var stop = text.indexOf('"', i + 1); 
      result.push('<span class="a">'); 
      result.push(text.substring(i, stop+1)); 
      result.push('</span>'); 
      i = stop; 
     } 
     else if (text[i] === '*') { 
      var stop = text.indexOf('*', i + 1); 
      result.push('<span class="b">'); 
      result.push(text.substring(i, stop+1)); 
      result.push('</span>'); 
      i = stop; 
     } 
     else if (text[i] === '<') { 
      // Skip simple HTML tags. 
      var stop = text.indexOf('>', i + 1); 
      result.push(text.substring(i, stop+1)); 
      i = stop; 
     } 
     else { 
      result.push(text.substring(i,i+1)); 
     } 
    } 
    return result.join(''); 
} 

例子:

>>> highlight('foo *bar"baz"qux* "foobar" qux') 
"foo <span class="b">*bar"baz"qux*</span> <span class="a">"foobar"</span> qux" 

或者使用正則表達式:

function highlight2(text) { 
    return text.replace(/([*"]).*?\1|<[^<>]*>/g, function (match, ch) { 
     // 'match' contains the whole match 
     // 'ch' contains the first capture-group 
     if (ch === '"') { 
      return '<span class="a">' + match + '</span>'; 
     } 
     else if (ch === '*') { 
      return '<span class="b">' + match + '</span>'; 
     } 
     else { 
      return match; 
     } 
    }); 
} 

正則表達式([*"]).*?\1包含以下內容:

  • [*"]匹配*"。 (他們不需要在[ ]內轉義)。
  • ()捕獲匹配的字符串爲捕獲組1
  • .*?匹配任何東西,直到第一...
  • \1相同的字符串相匹配的被捕獲到捕獲組1
  • |是「要麼」。它試圖匹配左側,如果失敗,它會嘗試匹配右側。
  • <[^<>]*>符合簡單的html標籤。這不會是能夠處理與他們的文字<>屬性:<a href="info.php?tag=<i>">(即壞的HTML反正,但有些瀏覽器會接受它。)

在這種情況下,當一個HTML標籤相匹配時,ch參數將爲undefined,並且將挑選else分支。

如果你想添加更多的字符,只需將它們放入[ ],並添加一個if語句來處理它們。您可以使用除-\]之外的任何字符,而不會將其轉義。要添加這些字符,您需要在其前面放置另一個\

+0

此失敗使用該試驗字符串: 亮點( '看<跨度類= \ 「一個\」> 「測試」')給出以下: 「請看 \「a> \」test「 –

+0

它不應該被多次應用。如果您願意,我可以更新它,以便它會嘗試忽略HTML標籤。 –

0

你的基本算法是

function highlight(myInput) { 
    // Split the string into tokens. 
    // "[^"]*" matches a minimal run surrounded by quotes 
    // \*[^*]*\* matches a minimal run surrounded by asterisks 
    // ["*][^"*]* matches an unmatched quote or asterisk and the tail of the string 
    // [^"*]+  matches a maximal un-styled run 
    var tokens = myInput.match(/"[^"]*"|\*[^*]*\*|["*][^"*]*$|[^"*]+/g); 

    // Walk over the list of tokens and turn them into styled HTML 
    var htmlOut = []; 
    for (var i = 0, n = tokens.length; i < n; ++i) { 
    var token = tokens[i]; 
    // Choose a style. 
    var className = 
     token.charAt(0) == '"' ? "a" : token.charAt(0) == '*' ? "b" : null; 
    // Surround in a span if we have a style. 
    if (className) { htmlOut.push("<span class='", className, "'>"); } 
    // HTML escape the token content. 
    htmlOut.push(token.replace(/&/g, "&amp;").replace(/</g, "&lt;")); 
    if (className) { htmlOut.push("</span>"); } 
    } 
    // Join the output tokens. 
    return htmlOut.join(''); 
} 


alert(highlight('"hello" *world*'));