【问题标题】:Using regex in python to return capitalized words between a specific word在python中使用正则表达式返回特定单词之间的大写单词
【发布时间】:2023-03-30 05:14:02
【问题描述】:

我不熟悉使用正则表达式。

我有一个格式为

的字符串
                Waco, Texas     

                Unit Dose 13 and 





           SECTION 011100       SUMMARY OF WORK





    INDEX   PAGE



PART 1. - GENERAL   1

1.1.    RELATED DOCUMENTS   1

1.2.    PROJECT DESCRIPTION 1

1.3.    OWNER   1

1.4.    ARCHITECT/ENGINEER  2

1.5.    PURCHASE CONTRACTS  2

1.6.    OWNER-FURNISHED ITEMS   2

1.7.    CONTRACTOR-FURNISHED ITEMS  3

1.8.    CONTRACTOR USE OF PREMISES  3

1.9.    OWNER OCCUPANCY 3

1.10.   WORK RESTRICTIONS   4

PART 2. - PRODUCTS - NOT APPLICABLE 4

PART 3. - EXECUTION - NOT APPLICABLE    4

我为额外的空白道歉,但这是我解析以获得字符串的 word 文档的形式。

我需要捕获 PART 1 PART 2 和 PART 3 之间的所有标题,并将它们存储在不同的列表中。到目前为止我有

matchedtext = re.findall('(?<=PART) (.*?) (?=PART)', text, re.DOTALL)

如果我理解正确,这些环顾四周应该使用 PART 作为一种基点,并抓住中间的文本。但是,当我运行代码时,matchedtext 不会填充任何内容。

我的问题的第二部分是,一旦我在 PART 的不同出现之间有文本,我如何才能将大写标题保存在列表中,每个标题都有一个字符串。我的 word 文档中的一些字符串包含小写单词,但我只想要全部大写的单词。

所以总结一下如何在字符串中的特定单词之间获取文本,一旦有了它们,我如何将单词保存为列表中的单个字符串。

感谢您的帮助! :D

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    您甚至不需要使用正则表达式,只需对字符串使用 split 函数即可。如果 s 是您的字符串的名称,它将是:

    s.split('PART')
    

    这将包括第一个 PART 之前的文本,所以不要使用列表的第一个元素:

    texts_between_parts = s.split('PART')[1:]
    

    您可以稍后使用字符串方法isupper检查一个单词是否全部大写。

    【讨论】:

    • 好的,split 是一个很酷的技巧,但我不确定 isupper 是否会起作用,原因有几个。有时我的字符串包含带有句子的潜文本,所以 isupper 会在句子的开头抓住大写的单词。我尝试使用 isupper real quick 与 upper = ''.join([c for c in text_between_parts if c.isupper()]) 并且它也没有省略数字。这就是我尝试使用正则表达式的原因
    • 试试[s for s in c.split() for c in texts_between_parts if s.isupper() and s.isalpha()]
    • 很抱歉,这是一个新问题,但该代码无法正常工作,因为它会返回文本 3 次。我正在尝试使用 stackoverflow.com/questions/17006641/… 了解其中发生的情况,但我似乎无法理解,你能向我解释一下吗?谢谢
    • 使用 for 循环代替双重列表理解。
    【解决方案2】:

    我会忘记抓住第 1 部分和第 2 部分之间的所有内容,等等。我将使用以下正则表达式解析每一行,并使用 Group 1 来确定标题的分组。

    ^(\d)(\.|\d)+\s+([^a-z]+?)\s+\d$
    

    第 1 组是零件编号/部分

    第 2 组是子节

    第 3 组是标题

    import re
    
    p = re.compile('^(\d)(\.|\d)+\s+([^a-z]+?)\s+\d$')
    
    m = p.match( '1.4.    ARCHITECT/ENGINEER  2' )
    
    if m:
    
        print('Match found: ', m.groups())
    
    else:
    
        print('No match')
    

    找到匹配项:('1', '.', 'ARCHITECT/ENGINEER')

    【讨论】:

    • 您能解释一下这个正则表达式的作用吗?这比我现在的能力略高。 [^a-z] 也应该是 [^A-Z] 因为它正在寻找大写的单词?它会像这样实现吗? matches = re.search('^(\d)(\.|\d)+\s+([^a-z]+?)\s+\d$', text) ?谢谢
    • ^ 行首 (\d) 为第一个数字/节号创建一个组 (\.|\d) 创建第二个组,捕获 0 个或多个小节号 .1.1 \s+ 捕获任何空格([^az]) 创建第三组,捕获不包含小写字母的任何内容 \s+ 捕获剩余空格 \d$ 捕获行尾的页码
    • 好的,这是有道理的,但是当我运行它时,它没有找到任何匹配项。我目前正在尝试找出原因。
    • 任何关于为什么会很棒的想法。谢谢
    • 贴一些realdata.txt,我看看。
    【解决方案3】:
    import re
    p = re.compile('^(\d)(\.|\d)+\s+([^a-z]+?)\s+\d$')
    m = p.match( '1.4.    ARCHITECT/ENGINEER  2' )
    if m:
        print('Section: ', m.group(1))
        print('Heading: ', m.group(3))
    else:
        print('No match')
    
    # Output 
    # Section:  1
    # Heading:  ARCHITECT/ENGINEER
    

    【讨论】:

      猜你喜欢
      • 2021-04-20
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多