繁体   English   中英

用于解析单词结构的正则表达式

[英]Regular expression to parse word structure

我正在尝试构建我的第一个非平凡的正则表达式(用于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个字的单词:

<a consonant><a left-attaching vowel><an independent vowel>

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

我知道所有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范围。
  • (这似乎非常困难)允许的最小“结构”列表必须在以后扩展。 有没有办法在正则表达式中设置一种“循环”机制,以便它适用于列表中的所有允许结构?

任何帮助,将不胜感激。 这对初学者来说似乎非常复杂!

用于具有非平凡形态的语言的形态分析的适当工具是“有限状态传感器”。 您可以跟踪和使用强大的实现(一个由Xerox Parc提供)。 有一个有python绑定(用作外部库)。 谷歌一下。

FST基于有限状态自动机,如(纯)正则表达式,但它们绝不是替代品。 这是复杂的机器,所以如果你的目标很简单(例如,用于连字的音节),你可能想要寻找更简单的东西。 例如,有机器学习算法将“学习”连字符。 如果您确实对形态分析感兴趣,那么您必须努力查看FST。

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

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

PS。 您可能知道这一点,但如果您将以下内容作为脚本中的第二行,则可以将孟加拉语嵌入到正则表达式中:

# -*- coding: utf-8 -*-
  • 我需要将正则表达式拆分为多行,否则代码看起来会很糟糕。 我该怎么做呢?

编译正则表达式时使用re.VERBOSE标志。

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

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

>>> subpatterns = {"vowel": "[aeiou]", "consonant": "[^aeiou]"}
>>> "{consonant}{vowel}+{consonant}*".format(**subpatterns)
'[^aeiou][aeiou]+[^aeiou]*'
  • 允许的最小“结构”列表必须在以后扩展。 有没有办法在正则表达式中设置一种“循环”机制,以便它适用于列表中的所有允许结构?

我不确定我是否理解你的意思,但是......假设你有一个(未编译的)RE列表,比如patterns ,那么你可以用它来计算它们的联合

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

在以这种方式构造RE时要小心特殊字符,并在必要时使用re.escape

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM