2012-01-12 193 views
1

我需要從字符串中提取不同類型的術語。我成功地提取我的字母數字字符,貨幣數字和不同的數字格式與此正則表達式:表情符號匹配 - PHP

$numalpha = '(\d+[a-zA-Z]+)'; 
$digitsPattern = '(\$|€|£)?\d+(\.\d+)?'; 
$wordsPattern = '[\p{L}]+'; 
preg_match_all('/('.$numalpha. '|' .$digitsPattern.'|'.$wordsPattern.')/ui', $str, $matches); 

我還需要匹配表情。我整理了以下的正則表達式:

#(^|\W)(\>\:\]|\:-\)|\:\)|\:o\)|\:\]|\:3|\:c\)|\:\>|\=\]|8\)|\=\)|\:\}|\:\^\)|\>\:D|\:-D|\:D|8-D|x-D|X-D|\=-D|\=D|\=-3|8-\)|\>\:\[|\:-\(|\:\(|\:-c|\:c|\:-\<|\:-\[|\:\[|\:\{|\>\.\>|\<\.\<|\>\.\<|\>;\]|;-\)|;\)|\*-\)|\*\)|;-\]|;\]|;D|;\^\)|\>\:P|\:-P|\:P|X-P|x-p|\:-p|\:p|\=p|\:-Þ|\:Þ|\:-b|\:b|\=p|\=P|\>\:o|\>\:O|\:-O|\:O|°o°|°O°|\:O|o_O|o\.O|8-0|\>\:\\|\>\:/|\:-/|\:-\.|\:\\|\=/|\=\\|\:S|\:'\(|;'\()($|\W)# 

這似乎多達工作在一定程度上:code

看來它不工作了位於該字符串的結尾表情,即使我指定

($|\W) 

正則表達式中。

------------------編輯-----------------

我刪除了($ | W),正如Tiddo所建議的那樣,它現在在字符串的末尾匹配表情符號。問題是包含(^ | \ W)的正則表達式也與表情符號前面的字符相匹配。

對於測試字符串:

$str = ":) Testing ,,:) ::) emotic:-)ons ,:(:D :O hsdhfkd :("; 

的匹配是如下:

(
[0] => :) 
[1] => ,:) 
[2] => ::) 
[3] => ,:(
[4] => :D 
[5] => :O 
[6] => :(
) 

(在 ' ''' 和 '::)' 在也匹配 ''和 ':(' 條款)

Online code snippet

如何這個問題能解決?

+3

你的測試字符串是什麼? – MrGlass 2012-01-12 17:07:29

+0

'($ | \ W)'是一個表情嗎?這是什麼意思? – 2012-01-12 17:16:24

+0

@Shiplu'$'表示行結束。該模式*應該*檢查它是否是行結尾或不是單詞。 – Josh 2012-01-12 17:20:47

回答

1

其實,如果你基於正預測先行改變$full分配到這個表達式:

$full = "#(?=^|\W|\w)(" . $regex .")(?=\w|\W|$)#"; 

或者乾脆這一沒有任何字邊界

$full = "#(" . $regex .")#"; 

如您所願,沒有它會工作任何問題。看到這裏http://ideone.com/EcCrD

說明工作代碼:在你原來的代碼你有:

$full = "#(^|\W)(" . $regex . ")(\W|$)#"; 

裏面還匹配,並搶得字邊界。現在考慮何時多個匹配表情符號被單個單詞邊界(如空格)分開。在這種情況下,正則表達式匹配第一個表情符,但抓取包含空格字符的文本。現在對於第二個表情符號,它找不到字邊界,即\W,但無法抓住該邊界。

在我的回答中,我使用的是積極lookahead,但實際上並沒有抓住字邊界,因此它按預期工作並匹配所有表情符號。