正则表达式处理单词结构

2024-07-03 06:56:56 发布

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

在我的Python中,我正在努力构建一个普通表达式,但我首先要使用的是非Python表达式。在

让我们假设X语言(不是英语)中的一个单词是一个最小的“结构”序列。每个“结构”可以是:

An independent vowel (basically one letter of the alphabet)
A consonant (one letter of the alphabet)
A consonant followed by a right-attaching vowel
A left-attaching vowel followed by a consonant
(Certain left-attaching vowels) followed by a consonant followed by (certain right-attaching vowels)

例如这个由3个字符组成的单词:

^{pr2}$

不是一个有效单词,并且不应与正则表达式匹配,因为在左附加元音的右侧没有辅音。在

我知道所有的Unicode范围-辅音、独立元音、左附加元音的Unicode范围等等。在

以下是我目前所掌握的情况:

WordPattern = (
ur'('
ur'[\u0985-\u0994]|'
ur'[\u0995-\u09B9]|'
ur'[\u0995-\u09B9(\u09BE|[\u09C0-\u09C4])]|'
ur'[(\u09BF|\u09C7|\u09C8)\u0995-\u09B9]|'
ur'[(\u09BF|\u09C7|\u09C8)\u0995-\u09B9(\u09BE|[\u09C0-\u09C4])]'
ur')+'
)

它不起作用。除了让它发挥作用外,我还有三个具体问题:

  • 我需要将正则表达式拆分成多行,否则代码看起来会很糟糕。我该怎么做?在
  • 我想使用某种类型的字符串替换/模板来“命名”Unicode范围,以提高代码可读性并防止多次键入Unicode范围。在
  • (这似乎非常困难)允许的最小“结构”列表将在以后扩展。有没有办法在正则表达式中设置一种“循环”机制,使其适用于列表中所有允许的结构?在

任何帮助都将不胜感激。对于初学者来说这似乎很复杂!在


Tags: by表达式unicode单词结构one元音letter
2条回答
  • 我需要将正则表达式拆分成多行,否则代码看起来会很糟糕。我该怎么做?在

编译正则表达式时使用^{}标志。在

pattern = re.compile(r"""(
                            [\u0985-\u0994]  # comment to explain what this is
                          | [\u0995-\u09B9]
                          # etc.
                         )
                      """, re.VERBOSE)
  • 我想使用某种类型的字符串替换/模板来“命名”Unicode范围

可以从普通Python字符串构造RE:

^{pr2}$
  • 允许的最小“结构”列表将在以后扩展。有没有办法在正则表达式中设置一种“循环”机制,使其适用于列表中所有允许的结构?在

我不知道我是否明白你的意思,但是。。。假设您有一个(未编译)REs的列表,比如,patterns,那么您可以使用

re.compile("(%s)" % "|".join(patterns))

以这种方式构造REs时要注意特殊字符,必要时使用^{}。在

对具有非平凡形态的语言进行形态分析的合适工具是“有限状态传感器”。有一些健壮的实现可以跟踪并使用(xeroxparc的一个)。有一个具有python绑定(用作外部库)。谷歌吧。在

fst是基于有限状态自动机的,就像(纯)正则表达式一样,但它们决不是一个替代品。这是一个复杂的机制,所以如果你的目标很简单(例如,为了连字符的目的,音节化),你可能想找更简单的东西。例如,有一些机器学习算法可以“学习”连字符。如果你真的对形态分析感兴趣,你就得花点功夫去研究fst。在

现在,对于您的算法,如果您真的只需要一个简单的实现:因为任何元音或辅音都可以是独立的,您的规则是模棱两可的:它们允许“ab”被解析为“a-b”。这种模糊性意味着regexp方法可能永远不会起作用,但是如果先使用较长的regexp,则可能会获得更好的结果,因此当两者都适用时,它们优先于短的regexp。但实际上,您需要构建一个解析器(手动或使用模块),并分步尝试不同的东西。这与您想象的相反:设置一个使用不同regexp的循环,并逐步“消耗”字符串。在

然而,在我看来,你所描述的基本上是音节化。音节的基本规则是这样的:一个音节由一个核心元音,加上语言规则允许的任意多个前(“开始”)辅音,再加上任何不属于下一个音节的辅音。这条规则被称为“最大化开始”,其结果是,向后(从单词末尾)解析音节更容易。试试看。在

注:您可能知道这一点,但如果您将以下内容作为脚本的第二行,则可以在regexp中嵌入孟加拉语:

# -*- coding: utf-8 -*-

相关问题 更多 >