首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使标题大小写正则表达式与前缀标题匹配?

如何使标题大小写正则表达式与前缀标题匹配?
EN

Stack Overflow用户
提问于 2011-05-27 09:24:48
回答 1查看 883关注 0票数 1

我需要从一段文本中提取可能的标题。因此,例如,我想匹配"Joe Smith“、”公司“或”美利坚合众国“之类的词。我现在需要修改它以匹配以某种标题开头的名称(比如"Dr. Joe Smith")。下面是我的正则表达式:

代码语言:javascript
运行
复制
NON_CAPPED_WORDS = (
    # Articles
    'the',
    'a',
    'an',

    # Prepositions
    'about',
    'after',
    'as',
    'at',
    'before',
    'by',
    'for',
    'from',
    'in',
    'into',
    'like',
    'of',
    'on',
    'to',
    'upon',
    'with',
    'without',
    )

TITLES = (
    'Dr\.',
    'Mr\.',
    'Mrs\.',
    'Ms\.',
    'Gov\.',
    'Sen\.',
    'Rep\.',
    )

# These are words that don't match the normal title case regex, but are still allowed
# in matches
IRREGULAR_WORDS = NON_CAPPED_WORDS + TITLES

non_capped_words_re = r'[\s:,]+|'.join(IRREGULAR_WORDS)
TITLE_RE = re.compile(r"""(?P<title>([A-Z0-9&][a-zA-Z0-9]*[\s,:-]*|{0})+\s*)""".format(non_capped_words_re))

它构建以下正则表达式:

代码语言:javascript
运行
复制
(?P<title>([A-Z0-9&][a-zA-Z0-9]*[\s,:-]*|the[\s:,]+|a[\s:,]+|an[\s:,]+|about[\s:,]+|after[\s:,]+|as[\s:,]+|at[\s:,]+|before[\s:,]+|by[\s:,]+|for[\s:,]+|from[\s:,]+|in[\s:,]+|into[\s:,]+|like[\s:,]+|of[\s:,]+|on[\s:,]+|to[\s:,]+|upon[\s:,]+|with[\s:,]+|without[\s:,]+|Dr\.[\s:,]+|Mr\.[\s:,]+|Mrs\.[\s:,]+|Ms\.[\s:,]+|Gov\.[\s:,]+|Sen\.[\s:,]+|Rep\.)+\s*)

不过,这似乎不起作用:

代码语言:javascript
运行
复制
>>> whitelisting.TITLE_RE.findall('Dr. Joe Smith')
[('Dr', 'Dr'), ('Joe Smith', 'Smith')]

有没有更好的regex-fu的人可以帮我解决这个乱七八糟的regex?

EN

Stack Overflow用户

回答已采纳

发布于 2011-05-27 11:35:19

问题似乎是,表达式的第一部分[A-Z0-9&][a-zA-Z0-9]*[\s,:-]*吞噬了“前缀标题”中的首字母,因为它们是以标题为大小写的,直到到达句点。因此,当+重复子表达式并遇到'Dr.'时,表达式的初始部分与'Dr'匹配,只留下不匹配的句号。

一个简单的解决方法是简单地将“特殊情况”移到表达式的前面,这样它们就会作为第一种方法而不是最后的方法进行匹配(这实际上只是将{0}从表达式的末尾移到前面):

代码语言:javascript
运行
复制
TITLE_RE = re.compile(r"""(?P<title>({0}|[A-Z0-9&][a-zA-Z0-9]*[\s,:-]*)+\s*)""".format(non_capped_words_re))

结果:

代码语言:javascript
运行
复制
>>> TITLE_RE.findall('Dr. Joe Smith');
[('Dr. Joe Smith', 'Smith')]

我可能会更进一步,修改表达式以避免[\s:,]+的所有重复,但我不确定除了让格式化的表达式看起来更漂亮之外,还有什么真正的好处:

代码语言:javascript
运行
复制
'|'.join(IRREGULAR_WORDS)
TITLE_RE = re.compile(r"""(?P<title>((?:{0})[\s:,]+|[A-Z0-9&][a-zA-Z0-9]*[\s,:-]*)+\s*)""".format(non_capped_words_re))
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6146885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档