表情符号匹配 - PHP

时间:2012-01-12 17:01:53

标签: php regex preg-replace preg-match-all

我需要从字符串中提取不同类型的术语。我成功地使用此正则表达式提取字母数字字符,货币编号和不同的数字格式:

$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)

在正则表达式中。

------------------ EDIT -----------------

我删除了($ | W),如Tiddo建议的那样,它现在匹配字符串末尾的表情符号。问题是包含(^ | \ W)的正则表达式也匹配表情符号前面的字符。

对于测试字符串:

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

比赛如下:

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

(',',''和':'也匹配':)'和':('条款)

Online code snippet

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

实际上,如果您根据积极前瞻将$full分配更改为此正则表达式:

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

或只是这个没有任何单词边界

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

它可以正常运行,没有任何问题。请参阅此处的工作代码http://ideone.com/EcCrD

说明:在原始代码中:

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

这也匹配并抓住字边界。现在考虑当多个匹配的表情符号被单个单词边界(例如空格)分开时。在这种情况下,正则表达式匹配第一个表情符号,但抓取包含空格字符的文本。现在对于第二个表情符号,它找不到单词边界,即\W并且无法抓住它。

在我的回答中,我使用的是正向前瞻但实际上没有抓住字边界,因此它按预期工作并匹配所有表情符号。