Unicode 字符的正则表达式范围字符 class 乱序
RegExp Range out of order in character class for Unicode Characters
我有这个正则表达式:
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}]');
当我在 https://regex101.com 上使用这个 RegExp 时,它工作正常。但是,当我在 Dart 中使用此 RegExp 时,出现 Range out of order in character class
错误(请注意,当我尝试使用 JavaScript 中的 RegExp
等价物时,也会发生同样的情况)。
我确定这是一个字符串转义错误,但我找不到问题所在。
我已经在 Dart (r'...'
) 中尝试了一个原始字符串,在 \u{1f300}
→ \u{1f300}
中转义了 \
,然而,两者都不起作用。
Unicode 匹配
正如评论中指出的,匹配unicode字符需要正则表达式中的unicode flag。
如果您尝试使用 RegExp('\u123')
简单地匹配 unicode 字符,这将失败,原因有两个。
- 正则表达式中不能有 unicode 字符。相反,您需要 转义 它们(例如,通过使用原始字符串):
RegExp(r'\u123')
.
- 这仍然行不通,因为现在正则表达式会尝试计算字符串中的每个字符(因此
\
、u
等)。这是 unicode flag 发挥作用的地方: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,
);
字素簇
您可能遇到的另一个问题是,您将无法将跨越多个字符的表情符号与初始正则表达式相匹配。请注意,在上面的代码片段中,我在末尾添加了一个 +
以匹配跨越多个字符的表情符号。
现在为了匹配单个表情符号,您需要 运行 字符串中每个 字符 上的正则表达式,由 字形定义簇。这可以使用 package:characters
.
来实现
示例实现可以是 found here。
我有这个正则表达式:
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}]');
当我在 https://regex101.com 上使用这个 RegExp 时,它工作正常。但是,当我在 Dart 中使用此 RegExp 时,出现 Range out of order in character class
错误(请注意,当我尝试使用 JavaScript 中的 RegExp
等价物时,也会发生同样的情况)。
我确定这是一个字符串转义错误,但我找不到问题所在。
我已经在 Dart (r'...'
) 中尝试了一个原始字符串,在 \u{1f300}
→ \u{1f300}
中转义了 \
,然而,两者都不起作用。
Unicode 匹配
正如评论中指出的,匹配unicode字符需要正则表达式中的unicode flag。
如果您尝试使用 RegExp('\u123')
简单地匹配 unicode 字符,这将失败,原因有两个。
- 正则表达式中不能有 unicode 字符。相反,您需要 转义 它们(例如,通过使用原始字符串):
RegExp(r'\u123')
. - 这仍然行不通,因为现在正则表达式会尝试计算字符串中的每个字符(因此
\
、u
等)。这是 unicode flag 发挥作用的地方: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,
);
字素簇
您可能遇到的另一个问题是,您将无法将跨越多个字符的表情符号与初始正则表达式相匹配。请注意,在上面的代码片段中,我在末尾添加了一个 +
以匹配跨越多个字符的表情符号。
现在为了匹配单个表情符号,您需要 运行 字符串中每个 字符 上的正则表达式,由 字形定义簇。这可以使用 package:characters
.
示例实现可以是 found here。