如何修改PHP正则表达式以完整捕获Emoji Unicode转义序列?
如何修改正则表达式以完整捕获Emoji Unicode转义序列?
我使用以下正则表达式在preg_match_all中对$text变量内容进行分词:
preg_match_all( "/'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/", $text, $matches );
$text变量的内容为:
"Hello!! I'm Sajjad Hossain Sagor. It's 2023. w00t :D \ud83e\udd17"
其中\ud83e\udd17是🤗的Emoji Unicode转义序列,我希望将其作为单个匹配项捕获,但当前正则会将其拆分匹配,输出结果如下:
array (size=23) 0 => string 'Hello' (length=5) 1 => string '!!' (length=2) 2 => string ' I' (length=2) 3 => string ''m' (length=2) 4 => string ' Sajjad' (length=7) 5 => string ' Hossain' (length=8) 6 => string ' Sagor' (length=6) 7 => string '.' (length=1) 8 => string ' It' (length=3) 9 => string ''s' (length=2) 10 => string ' 2023' (length=5) 11 => string '.' (length=1) 12 => string ' w' (length=2) 13 => string '00' (length=2) 14 => string 't' (length=1) 15 => string ' :' (length=2) 16 => string 'D' (length=1) 17 => string ' \' (length=2) 18 => string 'ud' (length=2) 19 => string '83' (length=2) 20 => string 'e' (length=1) 21 => string '\' (length=1) 22 => string 'udd' (length=3) 23 => string '17' (length=2)
请问如何修改上述正则表达式以将该Emoji Unicode转义序列捕获为单个匹配项?
解决方案
在正则表达式最前端添加匹配连续Unicode转义序列的规则,利用正则的匹配优先级,优先捕获完整的Emoji转义部分。修改后的代码如下:
preg_match_all( "/(?:\\\\u[0-9a-fA-F]{4})+|'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/", $text, $matches );
关键修改说明:
(?:\\\\u[0-9a-fA-F]{4})+:这是一个非捕获组,用于匹配一个或多个连续的Unicode转义序列(格式为\u后跟4位十六进制字符)。由于Emoji常由多个代理对转义序列组成(比如\ud83e\udd17是两个转义序列),这个模式能将整个Emoji的转义部分作为单个整体捕获。- 将该模式放在正则最前面,确保它优先于其他通用字符匹配规则执行,避免Emoji转义序列被拆分成零散的字符片段。
修改后,\ud83e\udd17会被作为单个匹配项捕获,同时原有分词逻辑不受影响。
内容的提问来源于stack exchange,提问作者Sajjad Hossain Sagor
相关产品推荐
相关产品推荐

