【问题标题】:Regex to match words with first capital letter正则表达式匹配第一个大写字母的单词
【发布时间】:2015-10-22 20:36:54
【问题描述】:

尝试使用正则表达式识别我的文本数据的结构并遇到障碍。

对于下面的示例文本

我是一个标题:
Lorem Ipsum 只是打印的虚拟文本 和排版行业。 Lorem Ipsum 一直是业界的 自 1500 年代以来的标准虚拟文本。

I AM A TAB-Lorem Ipsum 只是打印的虚拟文本

我下面的正则表达式选择了 'I AM A HEADER:' 和 'I AM A TAB-'

^\s*(?:\b[A-Z]+\b[\s]*)+(?:[:-])\s*$

请提出修改建议以匹配“我是标题”和“我是标签”以及 忽略结束标记 ':' 和 '-'。

【问题讨论】:

  • ^\s*(?:(?=.+[:-]\s*$)(?:\b[A-Z][a-z]*\b[\s]*)+) 应该可以工作
  • 为什么要使用正则表达式? for myword in line.split(): if myword[0] == myword[0].upper() and myword[0].isalpha(): # do something

标签: python regex


【解决方案1】:

你可以使用

^\s*(?:\b[a-zA-Z]+\b\s*)+(?=[:-])

regex demo

正则表达式分解:

  • ^ - 字符串开头
  • \s* - 0 个或多个空格
  • (?:\b[a-zA-Z]+\b\s*)+ - 1 个或多个序列
    • \b - 字边界(冗余)
    • [a-zA-Z]+ - 1 个或多个字母
    • \b\s* - 0 个或多个空格。
  • (?=[:-]) - 前瞻要求 :- 紧跟在前面的子模式之后

这里的要点是将[a-z] 添加到[A-Z] 范围,删除\s*$ 并将(?:...) 非捕获组转为前瞻(不消耗字符)。

【讨论】:

  • 我可以限制可以出现在结束标记之前的字数吗?说 1 到 4 个单词。怎么样?
  • 不用担心。知道了。谢谢。
  • 是的,我猜想用{n} 替换+,其中n 是数字。 {2} 是一个限制量词,正好匹配前面的子模式 2 次。
【解决方案2】:

这是@stribizhev 的解决方案,效果非常好。

^\s*(?:\b[a-zA-Z]+\b\s*)+(?=[:-])

对于像我这样的新手,这是对解决方案的简单解释:

> ^\s      Anchor to the white space (tab, newline, blankspace)
> *        Look for repetition of white space if any 
> (?:      Start a non-capturing group 
> \b       Look for a word 
> [a-zA-Z] Anyword that starts with either a capital or small alphabet
> +        Look for repeating capital/small alphabets
> \s*      Match a blank space after the word 
> )+       Repeat 
> (?=      Ignore what follows (my best guess) 
> [:-]     Look for ':' or '-'

本质上,这个正则表达式在换行符中查找一组单词,后跟 ':' 或 '-'

通过添加 {n, m} as 来告诉它除了多少单词之外您开始丢失相关信息,从而使上述表达式更智能

^[\s]*(?:\b[a-zA-Z]+\b[\s]*){1,3}(?=[:-])

【讨论】:

  • 我认为你不需要 +{1,3} 之后,因为量词已经很贪婪了。 Python 不支持所有格量​​词。
  • @stribizhev:谢谢。编辑了答案。
猜你喜欢
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多