Unicode字符的字符类中的RegExp范围无序



我有这个RegExp:

RegExp(r'[u{1f300}-u{1f5ff}u{1f900}-u{1f9ff}u{1f600}-u{1f64f}u{1f680}-u{1f6ff}u{2600}-u{26ff}u{2700}-u{27bf}u{1f1e6}-u{1f1ff}u{1f191}-u{1f251}u{1f004}u{1f0cf}u{1f170}-u{1f171}u{1f17e}-u{1f17f}u{1f18e}u{3030}u{2b50}u{2b55}u{2934}-u{2935}u{2b05}-u{2b07}u{2b1b}-u{2b1c}u{3297}u{3299}u{303d}u{00a9}u{00ae}u{2122}u{23f3}u{24c2}u{23e9}-u{23ef}u{25b6}u{23f8}-u{23fa}u{200d}]');

当我在上使用此RegExp时https://regex101.com,它正在工作。但是当我在Dart中使用这个RegExp时,我会得到一个Range out of order in character class错误(注意,当我在JavaScript中使用等效的RegExp时也会发生同样的情况(。

我确信这是一个字符串转义错误,但我找不到问题所在。

我已经在Dart(r'...'(中尝试了一个原始字符串,在u{1f300}中转义了→然而,\u{1f300}都不起作用。

Unicode匹配

正如注释中所指出的,匹配unicode字符需要正则表达式中的unicode标志

如果您尝试使用RegExp('u123')简单地匹配unicode字符,那么这将失败,原因有两个。

  1. 正则表达式中不能有unicode字符。相反,您需要转义它们(例如使用原始字符串(:RegExp(r'u123')
  2. 这仍然不起作用,因为现在regex试图计算字符串中的每个字符(因此u等(。这就是unicode标志发挥作用的地方:RegExp('u123', unicode: true)

请注意,对于3字节的unicode字符,您需要添加大括号,例如RegExp(r'u{1f300}'。有关详细信息,请参阅此问题。


这意味着您的最终正则表达式应该如下所示:

RegExp(
r'[u{1f300}-u{1f5ff}u{1f900}-u{1f9ff}u{1f600}-u{1f64f}'
r'u{1f680}-u{1f6ff}u{2600}-u{26ff}u{2700}'
r'-u{27bf}u{1f1e6}-u{1f1ff}u{1f191}-u{1f251}'
r'u{1f004}u{1f0cf}u{1f170}-u{1f171}u{1f17e}'
r'-u{1f17f}u{1f18e}u{3030}u{2b50}u{2b55}'
r'u{2934}-u{2935}u{2b05}-u{2b07}u{2b1b}'
r'-u{2b1c}u{3297}u{3299}u{303d}u{00a9}'
r'u{00ae}u{2122}u{23f3}u{24c2}u{23e9}'
r'-u{23ef}u{25b6}u{23f8}-u{23fa}u{200d}]+',
unicode: true,
);

石墨烯簇

您可能会遇到的另一个问题是,您将无法将跨多个字符的表情符号与初始正则表达式进行匹配。请注意,在上面的片段中,我在末尾添加了一个+,以便匹配跨越多个字符的表情符号。

为了现在匹配单个表情符号,您需要在字符串中的每个字符上运行regex,由字形簇定义。这可以使用package:characters来实现。

这里可以找到一个示例实现。

最新更新