正则表达式以匹配大写/特殊/ Unicode /越南语字符

时间:2018-06-26 04:56:42

标签: python regex

我遇到了一个问题。确实,我使用越南文字,并且我想查找每个包含大写字母(大写字母)的单词。 当我使用“ re”模块时,我的函数(temp)无法捕获“Đà”之类的词。 另一种方法(temp2)是一次检查每个字符,它可以工作,但是速度很慢,因为我必须将句子拆分成单词。

因此,我想知道是否有一种“重新”模块可以捕获所有特殊大写字母的方法。

我有2种方法:

def temp(sentence):
    return re.findall(r'[a-z]*[A-Z]+[a-z]*', sentence)


lis=word_tokenize(sentence)
def temp2(lis):
    proper_noun=[]
    for word in lis:
        for letter in word:
            if letter.isupper():
                proper_noun.append(word)
                break
    return proper_noun

输入:

'nous avons 2 Đồng et 3 Euro'

预期输出:

['Đồng','Euro']

谢谢!

3 个答案:

答案 0 :(得分:5)

您可以使用此正则表达式:

\b\S*[AĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴAĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴAĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴAĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴAĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴAĂÂÁẮẤÀẰẦẢẲẨÃẴẪẠẶẬĐEÊÉẾÈỀẺỂẼỄẸỆIÍÌỈĨỊOÔƠÓỐỚÒỒỜỎỔỞÕỖỠỌỘỢUƯÚỨÙỪỦỬŨỮỤỰYÝỲỶỸỴA-Z]+\S*\b

Regex Demo

答案 1 :(得分:1)

@Rizwan M.Tuman的答案是正确的。我想与您分享这三个功能执行100,000个句子的速度。

lis=word_tokenize(sentence)
def temp(lis):
    proper_noun=[]
    for word in lis:
        for letter in word:
            if letter.isupper():
                proper_noun.append(word)
                break
    return proper_noun

def temp2(sentence):
    return re.findall(r'[a-z]*[A-Z]+[a-z]*', sentence)

def temp3(sentence):
    return re.findall(capital_letter,sentence)

通过这种方式:

start_time = time.time()
for k in range(100000):
    temp2(sentence)
print("%s seconds" % (time.time() - start_time))

以下是结果:

>>Check each character of a list of words if it is a capital letter (.isupper())
(sentence has already been splitted into words)
0.4416656494140625 seconds

>>Function with re module which finds normal capital letters [A-Z] :
0.9373950958251953 seconds

>>Function with re module which finds all kinds of capital letters :
1.0783331394195557 seconds

答案 2 :(得分:1)

要只匹配至少1个包含至少1个大写Unicode字母的字母块,您可以使用

import re, sys, unicodedata

pLu = '[{}]'.format("".join([chr(i) for i in range(sys.maxunicode) if chr(i).isupper()]))
p = re.compile(r"[^\W\d_]*{Lu}[^\W\d_]*".format(Lu=pLu))

sentence = 'nous avons 2 Đồng et 3 Ęułro.+++++++++++++++Next line'
print(p.findall(sentence))
# => ['Đồng', 'Ęułro', 'Next']

pLu是使用unicodedata动态构建的Unicode字母字符类模式。它取决于Python版本,请使用最新版本来包含尽可能多的Unicode大写字母(请参见this answer for more details, too)。 [^\W\d_] is a construct matching any Unicode letter。因此,该模式匹配任何0+个Unicode字母,然后匹配至少1个Unicode大写字母,然后再具有任何0+ Unicode字母。

请注意,原始r'[a-z]*[A-Z]+[a-z]*'在此输入中只能找到Next

print(re.findall(r'[a-z]*[A-Z]+[a-z]*', sentence)) # => ['Next']

请参见Python demo

要将单词作为整个单词进行匹配,请使用\b单词边界:

p = re.compile(r"\b[^\W\d_]*{Lu}[^\W\d_]*\b".format(Lu=pLu))

如果要使用Python 2.x,请不要忘记使用re.U标志来使\W\d\b能够识别Unicode。但是,建议使用最新的PyPi regex库及其[[:upper:]] / \p{Lu}结构来匹配大写字母,因为它将支持Unicode字母的最新列表。