我正在尝试使用java替换阿拉伯语推文中的表情符号。
我使用了这段代码:
String line = "اييه تقولي اجل الارسنال تعادل امس بعد ما كان فايز ";
Pattern unicodeOutliers = Pattern.compile("([\u1F601-\u1F64F])", Pattern.UNICODE_CASE | Pattern.CANON_EQ | Pattern.CASE_INSENSITIVE);
Matcher unicodeOutlierMatcher = unicodeOutliers.matcher(line);
line = unicodeOutlierMatcher.replaceAll(" $1 ");
但它并没有取代它们。即使我只匹配角色本身" \ u1F602"它不会取代它。可能是因为它是你之后的5位数?!我不确定,只是一个猜测。
请注意:
1-推文()末尾的情绪是" U + 1F602"这是"面对欢乐的泪水"
2-这个问题与this question不重复。
任何想法?
答案 0 :(得分:5)
来自Javadoc for the Pattern
class
Unicode字符也可以用正则表达式表示 直接使用其十六进制表示法(十六进制代码点值) 在构造
\x{...}
中描述,例如补充字符 U + 2011F可以指定为\x{2011F}
,而不是连续两次 代理对\uD840\uDD1F
的Unicode转义序列。
这意味着您正在寻找的正则表达式为([\x{1F601}-\x{1F64F}])
。当然,当您将其写为Java String
文字时,必须转义反斜杠。
Pattern unicodeOutliers = Pattern.compile("([\\x{1F601}-\\x{1F64F}])");
请注意,构造\x{...}
仅可从Java 7获得。
答案 1 :(得分:5)
如果您在Java 5或6 JVM上运行程序时遇到困难,并且想要匹配U + 1F601到U + 1F64F范围内的字符,请在字符类中使用代理项对:
Pattern emoticons = Pattern.compile("[\uD83D\uDE01-\uD83D\uDE4F]");
即使在Java 7及更高版本中,此方法也是有效的,因为在Sun / Oracle的实现中,如果您反编译Pattern.compile()
方法,则在编译之前将包含该模式的String转换为代码点数组
您可以在David Wallace的答案中使用构造\x{...}
,该答案可从Java 7获得。
或者,您也可以指定整个Emoticons Unicode block,从代码点 U + 1F600 (而不是U + 1F601)到U + 1F64F。
Pattern emoticons = Pattern.compile("\\p{InEmoticons}");
由于在Java 7中添加了Emoticons block支持,因此该方法仅在Java 7中有效。
虽然首选其他方法,但您可以通过在正则表达式中指定转义来指定补充字符。虽然没有理由在源代码中执行此操作,但Java 7中的此更改会更正使用正则表达式进行搜索的应用程序中的行为,并且无法直接粘贴该字符。
Pattern emoticons = Pattern.compile("[\\uD83D\\uDE01-\\uD83D\\uDE4F]");
/!\
警告在指定补充代码点时,永远不会将语法混合在一起,例如:
"[\\uD83D\uDE01-\\uD83D\\uDE4F]"
"[\uD83D\\uDE01-\\uD83D\\uDE4F]"
这些将指定在Oracle的实现中匹配代码点U + D83D和代码点U + DE01到代码点U + 1F64F的范围。
在Java 5和6,Oracle的实现中,Pattern.u()
的实现不会折叠有效的正则表达式转义的代理对"\\uD83D\\uDE01"
。结果,模式被解释为2个单独的代理,这将无法匹配任何东西。