"狭窄" Python构建we should使用特殊的正则表达式模式来匹配代理对的范围。这种模式可能相当复杂:
# Pattern we want:
pattern = '[\U000105c0-\U0001cb40]'
# Pattern we should use in "narrow" build:
pattern = '(?:\uD801[\uDDC0-\uDFFF]|[\uD802-\uD831][\uDC00-\uDFFF]|\uD832[\uDC00-\uDF40])'
但是如何为给定的任意代理范围创建一个(例如\U000105c0
- \U0001cb40
)?
创建此模式的算法是什么?
Python中是否有现成的解决方案?
答案 0 :(得分:0)
安装http://www.regexformat.com应用。
(对于Windows)
您可以使用任何范围执行以下操作 只需要一个正则表达式来描述它(或任何东西)。
打开UCD Interface
http://imgur.com/S8V0mIG
在 Custom-Rx 页面上,输入[\x{105c0}-\x{1cb40}]
在输出中选择所需的转换语法
(这使用了\x{}
语法)。
点击按钮Get Hex Conversion
- > UTF-16
(一个菜单按钮)
复制“结果”框底部的正则表达式。
(?:
\x{D801} [\x{DDC0}-\x{DFFF}]
| [\x{D802}-\x{D831}] [\x{DC00}-\x{DFFF}]
| \x{D832} [\x{DC00}-\x{DF40}]
)
如果您将其粘贴到其中一个主应用程序文档中并且
结果压缩,结果
(?:\x{D801}[\x{DDC0}-\x{DFFF}]|[\x{D802}-\x{D831}][\x{DC00}-\x{DFFF}]|\x{D832}[\x{DC00}-\x{DF40}])
这里使用\uXXXX
语法
(?:\uD801[\uDDC0-\uDFFF]|[\uD802-\uD831][\uDC00-\uDFFF]|\uD832[\uDC00-\uDF40])
答案 1 :(得分:0)
我创建了处理我们可能需要的大多数情况的函数。
Python 2代码:
from __future__ import absolute_import, division, print_function, unicode_literals
__metaclass__ = type
import struct
def unichar(i):
"""
unichr for "narrow" builds.
"""
try:
return unichr(i)
except ValueError:
return struct.pack('i', i).decode('utf-32')
def get_pattern(char_from, char_to):
"""
Returns regex pattern for unicode chars that handles surrogates in "narrow" builds.
"""
if all(len(c) == 1 for c in (char_from, char_to)):
if char_from == char_to:
return char_from
else:
return '[{}-{}]'.format(char_from, char_to)
elif all(len(c) == 2 for c in (char_from, char_to)):
f1, f2 = [ord(i) for i in char_from]
t1, t2 = [ord(i) for i in char_to]
if t1 - f1 == 0:
p1 = '{}[{}-{}]'.format(unichar(f1), unichar(f2), unichar(t2))
return '(?:' + p1 + ')'
elif t1 - f1 == 1:
p1 = '{}[{}-\uDFFF]'.format(unichar(f1), unichar(f2))
p3 = '{}[\uDC00-{}]'.format(unichar(t1), unichar(t2))
return '(?:' + '|'.join([p1, p3]) + ')'
else:
p1 = '{}[{}-\uDFFF]'.format(unichar(f1), unichar(f2))
p2 = '[{}-{}][\uDC00-\uDFFF]'.format(unichar(f1+1), unichar(t1-1), unichar(f2))
p3 = '{}[\uDC00-{}]'.format(unichar(t1), unichar(t2))
return '(?:' + '|'.join([p1, p2, p3]) + ')'
else:
raise ValueError('Range is not supported by this function {}-{}'.format(char_from, char_to))
# Example:
if __name__ == '__main__':
print(repr(get_pattern('\U000105c0', '\U0001cb40')))
# (?:\ud801[\uddc0-\udfff]|[\ud802-\ud831][\udc00-\udfff]|\ud832[\udc00-\udf40])