2012-01-12 195 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,但实际上并没有抓住字边界,因此它按预期工作并匹配所有表情符号。