我需要从字符串中提取不同类型的术语。我成功地使用此正则表达式提取字母数字字符,货币编号和不同的数字格式:
$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] => :(
)
(',',''和':'也匹配':)'和':('条款)
如何解决这个问题?
答案 0 :(得分:1)
实际上,如果您根据积极前瞻将$full
分配更改为此正则表达式:
$full = "#(?=^|\W|\w)(" . $regex .")(?=\w|\W|$)#";
或只是这个没有任何单词边界:
$full = "#(" . $regex .")#";
它可以正常运行,没有任何问题。请参阅此处的工作代码http://ideone.com/EcCrD
说明:在原始代码中:
$full = "#(^|\W)(" . $regex . ")(\W|$)#";
这也匹配并抓住字边界。现在考虑当多个匹配的表情符号被单个单词边界(例如空格)分开时。在这种情况下,正则表达式匹配第一个表情符号,但抓取包含空格字符的文本。现在对于第二个表情符号,它找不到单词边界,即\W
并且无法抓住它。
在我的回答中,我使用的是正向前瞻但实际上没有抓住字边界,因此它按预期工作并匹配所有表情符号。