【问题标题】:Python regex capturing group extensionPython 正则表达式捕获组扩展
【发布时间】:2021-01-30 22:28:27
【问题描述】:

我正在使用命名捕获组,使用 (?P<name>) 以及与冠状病毒大流行相关的动词和词干列表。

import regex
import pandas as pd


data = {'id':[1, 2, 3, 4, 5], 'text':['The pandemy is spreading', 'He is fighting Covid-19', 'The pandemic virus spreads', 'This sentence is about a different topic' , 'How do we stop the virus ?']}
df = pd.DataFrame(data)

def covid_lang(text):    
    predicates = ['avoid', 'contain', 'track', 'spread', 'contact', 'stop', 'combat', 'fight']
    subjects = ['Corona', 'corona', 'Covid-19', 'epidem', 'infect', 'virus', 'pandem', 'disease', 'outbreak']

    p1 = fr'(?<=\b(?P<predicate>{"|".join(predicates)}))[^\.]*(?P<subject>{"|".join(subjects)}[a-z]*)'

    result = []
    for m in regex.finditer(p1, text, regex.S):
        result.append([m.group('predicate'), m.group('subject')])

    p2 = fr'\b(?P<subject>{"|".join(subjects)})[^\.]*(?<=\b(?P<predicate>{"|".join(predicates)}))'
    for m in regex.finditer(p2, text, regex.S):
        result.append([m.group('subject'), m.group('predicate')])

    return result

df['result'] = df['text'].apply(covid_lang)

当有匹配时,我想作为主语返回,不仅是词干,而且是整个词(即“pandemic”和“pandemy”而不是“pandem”)。我尝试在单词列表之后添加[a-z]*,以便捕获组在单词结束时停止,但它不会改变任何内容。

另外,是否可以在一个查询中加入两个查询(谓词在主语之前,主语在谓语之前)?我试过使用(p1)|(p2),但它不适用于命名的捕获组。

最后,是否可以在一个单词中包含大写和小写字母,例如 Coronacorona

【问题讨论】:

  • 绝对可以将 Corona 和 corona 包含在一个单词中用于 re.compile。设置 re.ignorecase 标志应该这样做flags。但除此之外我无能为力

标签: python regex capturing-group


【解决方案1】:

这应该做到所有三个:

from xml.etree.ElementPath import prepare_descendant

import regex
import pandas as pd

data = {'id':[1, 2, 3, 4, 5], 'text':['The pandemy is spreading', 'He is fighting Covid-19', 'The pandemic virus spreads', 'This sentence is about a different topic' , 'How do we stop the virus ?']}
df = pd.DataFrame(data)

def expand_word(word):
    return f'({word}[a-z]*)'

def construct_named_group_from_list_of_words(word_type, word_list):
    expanded_word_regex_list = [expand_word(stem) for stem in word_list]
    word_in_named_group = fr'(?P<{word_type}>{"|".join(expanded_word_regex_list)})'
    return word_in_named_group

def covid_lang(text):
    predicates = ['avoid', 'contain', 'track', 'spread', 'contact', 'stop', 'combat', 'fight']
    subjects = ['corona', 'covid-19', 'epidem', 'infect', 'virus', 'pandem', 'disease', 'outbreak']

    predicate_in_named_group = construct_named_group_from_list_of_words("predicate", predicates)
    subject_in_named_group = construct_named_group_from_list_of_words("subject", subjects)

    result = []

    p1 = fr'(?<=\b{predicate_in_named_group})[^\.]*{subject_in_named_group}'
    p2 = fr'\b{subject_in_named_group}[^\.]*(?<=\b{predicate_in_named_group})'

    p = fr'({p1})|({p2})'

    for m in regex.finditer(p, text, regex.S | regex.IGNORECASE):
        result.append([m.group('predicate'), m.group('subject')])


    return result


df['result'] = df['text'].apply(covid_lang)

print(df)

输出:

   id                                      text                  result
0   1                  The pandemy is spreading  [[spreading, pandemy]]
1   2                   He is fighting Covid-19     [[fight, Covid-19]]
2   3                The pandemic virus spreads   [[spreads, pandemic]]
3   4  This sentence is about a different topic                      []
4   5                How do we stop the virus ?         [[stop, virus]]

但我不确定你是否总是想先输出谓词?如果没有,应该这样做:

from xml.etree.ElementPath import prepare_descendant

import regex
import pandas as pd


data = {'id':[1, 2, 3, 4, 5], 'text':['The pandemy is spreading', 'He is fighting Covid-19', 'The pandemic virus spreads', 'This sentence is about a different topic' , 'How do we stop the virus ?']}
df = pd.DataFrame(data)

def expand_word(word):
    return f'({word}[a-z]*)'

def construct_named_group_from_list_of_words(word_type, word_list):
    expanded_word_regex_list = [expand_word(stem) for stem in word_list]
    word_in_named_group = fr'(?P<{word_type}>{"|".join(expanded_word_regex_list)})'
    return word_in_named_group

def covid_lang(text):
    predicates = ['avoid', 'contain', 'track', 'spread', 'contact', 'stop', 'combat', 'fight']
    subjects = ['corona', 'covid-19', 'epidem', 'infect', 'virus', 'pandem', 'disease', 'outbreak']

    predicate_in_named_group = construct_named_group_from_list_of_words("predicate", predicates)
    subject_in_named_group = construct_named_group_from_list_of_words("subject", subjects)

    result = []

    p1 = fr'(?<=\b{predicate_in_named_group})[^\.]*{subject_in_named_group}'
    p2 = fr'\b{subject_in_named_group}[^\.]*(?<=\b{predicate_in_named_group})'

    for m in regex.finditer(p1, text, regex.S | regex.IGNORECASE):
        result.append([m.group('predicate'), m.group('subject')])

    for m in regex.finditer(p2, text, regex.S | regex.IGNORECASE):
        result.append([m.group('subject'), m.group('predicate')])

    return result


df['result'] = df['text'].apply(covid_lang)

print(df)

输出:

   id                                      text                  result
0   1                  The pandemy is spreading  [[pandemy, spreading]]
1   2                   He is fighting Covid-19     [[fight, Covid-19]]
2   3                The pandemic virus spreads   [[pandemic, spreads]]
3   4  This sentence is about a different topic                      []
4   5                How do we stop the virus ?         [[stop, virus]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2019-01-12
    • 1970-01-01
    • 2019-03-17
    • 2018-07-21
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多