当前位置: 首页 > 知识库问答 >
问题:

使用正则表达式匹配仅以繁体中文出现的字符

汤飞羽
2023-03-14

\p{Han}可用于匹配所有汉字(汉文),这些汉字混合了简体中文和繁体中文。

是否有一个正则表达式只匹配繁体中文中唯一的字符?换句话说,匹配除简体中文以外的任何中文字符。类似(?!\p{Hans})\p{Hant}

此外,理想情况下,如果正则表达式还可以排除日本汉字、韩国汉字、越南友寿和友寿。

共有1个答案

李胤
2023-03-14

由于繁体字在Unicode表上是不连续的,因此不幸的是,除非Regex支持\p{Hant}\p{Hans}之类的东西,否则没有一个简单的Regex可以逐个测试它们。

受到@jdaz注释所指向的答案^的启发,我使用HanzIdentifier模块编写了一个Python脚本,生成与繁体中文&中唯一的字符匹配的正则表达式:

from typing import List, Tuple

from hanzidentifier import identify, TRADITIONAL


def main():
    block = [
        *range(0x4E00, 0x9FFF + 1),  # CJK Unified Ideographs
        *range(0x3400, 0x4DBF + 1),  # CJK Unified Ideographs Extension A
        *range(0x20000, 0x2A6DF + 1),  # CJK Unified Ideographs Extension B
        *range(0x2A700, 0x2B73F + 1),  # CJK Unified Ideographs Extension C
        *range(0x2B740, 0x2B81F + 1),  # CJK Unified Ideographs Extension D
        *range(0x2B820, 0x2CEAF + 1),  # CJK Unified Ideographs Extension E
        *range(0x2CEB0, 0x2EBEF + 1),  # CJK Unified Ideographs Extension F
        *range(0x30000, 0x3134F + 1),  # CJK Unified Ideographs Extension G
        *range(0xF900, 0xFAFF + 1),  # CJK Compatibility Ideographs
        *range(0x2F800, 0x2FA1F + 1),  # CJK Compatibility Ideographs Supplement
    ]
    block.sort()

    result: List[Tuple[int, int]] = []

    for point in block:
        char = chr(point)
        identify_result = identify(char)
        if identify_result is TRADITIONAL:
            # is traditional only, save into the result list
            if len(result) > 0 and result[-1][1] + 1 == point:
                # the current char is right after the last char, just update the range
                result[-1] = (result[-1][0], point)
            else:
                result.append((point, point))

    range_regexes: List[str] = []
    # now we have a list of ranges, convert them into a regex
    for start, end in result:
        if start == end:
            range_regexes.append(chr(start))
        elif start + 1 == end:
            range_regexes.append(chr(start))
            range_regexes.append(chr(end))
        else:
            range_regexes.append(f'{chr(start)}-{chr(end)}')

    # join them together and wrap into [] to form a regex set
    regex_char_set = ''.join(range_regexes)
    print(f'[{regex_char_set}]')


if __name__ == '__main__':
    main()

这将生成我在这里发布的正则表达式:https://regex101.com/r/fkkhq1/5(似乎堆栈溢出不喜欢我发布生成的正则表达式)

请注意,因为hanzidentifier使用的是CC-CEDICT,特别是它没有使用最新版本的CC-CEDICT,所以某些繁体字符肯定不会被覆盖,但对于常用字符应该足够了。

日本汉字是一个大集合。幸运的是,日本文化事务厅有一个常用汉字列表,因此我创建了这个文本文件供程序阅读。排除了常用的汉字后,我得到了这个regex:https://regex101.com/r/fkkhq1/7

不幸的是,我找不到一个常用韩文的列表。尤其是现在很少使用汉字。越南的友寿和友寿也几乎被消灭了。

脚注:

^:该答案中的正则表达式不匹配所有简体字符。要获得匹配所有简体字符(包括繁体中文字符)的正则表达式,请将if identify_result为繁体字符更改为if identify_result为简体字符或identify_result为两者字符,这样就得到了正则表达式:https://regex101.com/r/fkkhq1/6

&:此脚本不过滤日本汉字、韩国汉字、越南友寿或友寿。您必须修改它以排除它们。

 类似资料:
  • 问题内容: 我有以下字符串: 如您所见,该字符串由#分隔。我的用例类似于一个简单的SPLIT(string,“#”)操作,但是regex给了我更多的灵活性。 我想匹配两次出现的#之间的字符。例如,第二次和第三次出现之间的字符应匹配:“ US” 我使用的是Google Bigquery,能够匹配字符串的前两个术语,但与第三个术语比较费劲: 位置是字符串,例如上面的字符串。 我已经找到了这个问题,但是

  • 本文向大家介绍中文正则表达式匹配问题之正则表达式中文匹配使用方法,包括了中文正则表达式匹配问题之正则表达式中文匹配使用方法的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要讲如何使用正则匹配中文字符,中文正则表达式的匹配规则不像其他正则规则一样容易记住,下面一起看看这个中文正则表达式是怎么样的。 \w匹配的仅仅是中文,数字,字母,对于国人来讲,仅匹配中文时常会用到,见下 匹配中文字符的正则表达

  • 问题内容: 什么正则表达式将匹配Java中的任何ASCII字符? 我已经尝试过: 但是发现它与我想要的很多东西都不匹配(例如空格,括号等)。我希望避免以如下格式显式列出所有127个ASCII字符: 问题答案: 我没用过但是我用过

  • 问题内容: 我正在尝试创建一个匹配字符串的正则表达式,如果它连续有3个或多个重复字符(例如aaaaaa,testtttttt,otttttter)。 我尝试了以下方法: 连续 匹配 任意 3个字符,但不 连续的 字符…我在哪里出错? 问题答案: 您要的内容无法使用 真正的 正则表达式完成,您需要的是(不规则的)反向引用。尽管许多正则表达式引擎实现了它们,但Go使用的RE2却没有。RE2是一种快速的

  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 问题内容: 我正在尝试使用Java匹配多行文本。当我将类与修饰符一起使用时,我可以匹配,但不能. 使用和使用相同的模式似乎无效。 我确定我缺少什么,但不知道是什么。正则表达式不是很好。 这就是我尝试过的 问题答案: 首先,你在错误的假设下使用修饰符。 或告诉Java接受锚点并在每行的开头和结尾进行匹配(否则,它们仅在整个字符串的开头/结尾进行匹配)。 或告诉Java也允许点与换行符匹配。 其次,在