2011-06-13 26 views
3

我使用正則表達式片斷將笑臉解析爲圖像,並遇到分號問題。例如,表情符號等;)變成WINK圖標,針對在javascript正則表達式中跳過前面的html實體

/;-?\)/g 

匹配,並且在大多數情況下工作。但是像「」這樣的文本也與「WINK」匹配,因爲引號實際上是一個html實體(" => &quotWINK)。

我試圖附加了一個貪婪的非獲取匹配的正則表達式來丟棄分號實體:

(?:"|&|<|>|'|')? 

但所產生的圖案仍然匹配反對"分號應忽略,因爲它回溯到滿足非可選的後一部分。我也意識到,其他合法匹配仍然存在問題,例如EVIL:>:) => >:)

那麼看來我真的需要HTML實體缺少分號之前的否定

(?!&quot|&amp|&lt|&gt|&apos|&#039) 

但它仍然是匹配的,我不知道爲什麼。

這將是理想的仍然是返回的比賽,可以更換沒有進一步檢查批發,但我願意提出建議。不適合的是首先解析出html實體,因爲它們有時是必要的和/或是合法笑臉的一部分(與EVIL一樣)。


EDIT(一些谷歌的食物):

我發現(和Bryan也低於註明),由於所需的(不是零寬度負先行(?!regex))零寬度正回顧後,(?<!regex),會工作。

根據regular-expressions.info,後者「只有在前視內的正則表達式不匹配時纔會成功」,這聽起來是正確的,但不是當該部分是可選的時候。

相比之下,前者「匹配在一個位置,如果在該位置的內部模式可以匹配在該位置結束」,這一點根本不清楚,但是做到了。因爲這場比賽是使用逆序,所以沒有回溯的機會來滿足正則表達式的後一部分。

所以,一個完整的正則表達式的樣子:

/(?<!&quot|&amp|&lt|&gt|&apos|&#039);-?\)/g 

和匹配這些:;) => WINKblah;) => blahWINK&quot;;) => &quot;WINK而如果做不到:&quot;) 但它確實仍然匹配&amp;quot;) => &amp;quotWINK,讓更多的調整將是理想的(如額外的匹配分號代替&符號,如果這不會導致與其中的實體打破的其他笑臉)。無論如何,人們在聊天中輸入html實體的可能性不大。

無論哪種方式將是「足夠好」 - 除了JavaScript不支持負面倒車後衛。但爲了其他正則表達式的實現,這是值得解釋的。

回答

2

首先,您可以檢查;-)之前的空格字符,這是一個更簡單的選項。但是,如果你想實現在JavaScript negative lookbehind - 它存在於正則表達式的幾種口味,但不是在JS一個 - 你可以做這樣的事情:

var text = "& &amp; &amp;-) ;-) test;-)"; 
var ENTITIES_REGEX = /(&quot|&amp|&lt|&gt|&apos|&#039)?;-\)/g; 

var result = text.replace(ENTITIES_REGEX, function(fullMatch, backref1) { 
    // Ignore if there is a backreference by returning the unaltered 
    // match, otherwise return WINK 
    return (backref1 ? fullMatch : 'WINK'); 
}); 

// result equals "& &amp; &amp;-) WINK testWINK" 

而這裏的an example

+0

+1不錯的解決方案! – 2011-06-13 23:40:43

+0

完美的工作,即使在現有的回調內,處理避免笑臉解析內部網址。 :) ......對性能有點擔憂,但即使對於垃圾聊天者來說,它似乎也不是問題。擴展到'([&;] quot | [&;] amp | [&;] lt | [&;] gt | [&;] apos | [&;]#039)?'也似乎不成問題對於任何其他笑臉,儘管需要更多的測試。 – HonoredMule 2011-06-13 23:50:54