如何为任意范围的代理项对创建正则表达式模式

2024-09-28 05:27:14 发布

您现在位置:Python中文网/ 问答频道 /正文

在“窄”Python构建中,we should使用特殊的regex模式匹配代理项对的范围。这种模式可能相当复杂:

# 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中有现成的解决方案吗?在


Tags: in代理use模式regexwepatternshould
2条回答

安装http://www.regexformat.com应用。
(适用于windows)

您可以在任何范围内执行以下操作。
只需要一个正则表达式来描述它(或任何东西)。在

打开UCD Interfacehttp://imgur.com/S8V0mIG

自定义接收页面上,输入[\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])

我创建了一个函数来处理我们可能需要的大多数情况。在

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])

相关问题 更多 >

    热门问题