【问题标题】:How to find all words in a string that begin with an uppercase letter, for multiple strings in a list对于列表中的多个字符串,如何查找字符串中以大写字母开头的所有单词
【发布时间】:2020-07-17 15:35:29
【问题描述】:

我有一个字符串列表,每个字符串大约 10 个句子。我希望从每个字符串中找到所有以大写字母开头的单词。最好在句子的第一个词之后。我正在使用 re.findall 来执行此操作。当我手动设置 string = '' 时,这样做没有问题,但是当我尝试使用 for 循环遍历列表中的每个条目时,我会得到不同的输出。

for i in list_3:
    string = i
    test = re.findall(r"(\b[A-Z][a-z]*\b)", string)
print(test)

输出:

['I', 'I', 'As', 'I', 'University', 'Illinois', 'It', 'To', 'It', 'I', 'One', 'Manu', 'I', 'I', 'Once', 'And', 'Through', 'I', 'I', 'Most', 'Its', 'The', 'I', 'That', 'I', 'I', 'I', 'I', 'I', 'I']

当我手动输入字符串值时

txt = 0
for i in list_3:
    string = list_3[txt]
    test = re.findall(r"(\b[A-Z][a-z]*\b)", string)
print(test)

输出:

['Remember', 'The', 'Common', 'App', 'Do', 'Your', 'Often', 'We', 'Monica', 'Lannom', 'Co', 'Founder', 'Campus', 'Ventures', 'One', 'Break', 'Campus', 'Ventures', 'Universities', 'Undermatching', 'Stanford', 'Yale', 'Undermatching', 'What', 'A', 'Yale', 'Lannom', 'There', 'During', 'Some', 'The', 'Lannom', 'That', 'It', 'Lannom', 'Institutions', 'University', 'Chicago', 'Boston', 'College', 'These', 'Students', 'If', 'Lannom', 'Recruiting', 'Elite', 'Campus', 'Ventures', 'Understanding', 'Campus', 'Ventures', 'The', 'For', 'Lannom', 'What', 'I', 'Wish', 'I', 'Knew', 'Before', 'Starting', 'Company', 'I', 'Even', 'I', 'Lannom', 'The', 'There']

但我似乎无法编写一个 for 循环来正确打印列表中 5 项中的每一项的输出。有什么想法吗?

【问题讨论】:

    标签: python regex string findall capitalization


    【解决方案1】:

    最简单的方法是编写一个for 循环来检查列表元素的第一个字母是否大写。如果是,它将被附加到output 列表中。

    output = []
    for i in list_3:
        if i[0] == i[0].upper():
            output.append(i)
    print(output)
    

    我们也可以使用列表推导式并将其放在 1 行中。我们也在检查元素的第一个字母是否是大写字母。

    output = [x for x in list_3 if x[0].upper() == x[0]]
    print(output)
    

    编辑

    您想将句子作为列表的元素放置,因此这是解决方案。我们遍历list_3,然后使用split() 函数遍历每个单词。然后我们检查单词是否大写。如果是,则将其添加到output

    list_3 = ["Remember your college application process? The tedious Common App applications, hours upon hours of research, ACT/SAT, FAFSA, visiting schools, etc. Do you remember who helped you through this process? Your family and guidance counselors perhaps, maybe your peers or you may have received little to no help"]
    output = []
    for i in list_3:
        for j in i.split():
            if j[0].isupper():
                output.append(j)
    print(output)
    

    【讨论】:

    • 只能做if x[0].isupper()
    • 当我尝试运行此代码时,不是打印包含大写字母的单词,而是打印字符串的全部内容。我需要附加 i.upper 吗?
    • @AndrewLittle1 你能告诉我input吗?我以为你只是给它一个词。
    • 输入是一串句子,比如“还记得你的大学申请过程吗?繁琐的 Common App 申请、数小时的研究、ACT/SAT、FAFSA、访问学校等。你知道吗?”还记得谁在这个过程中帮助过你吗?也许是你的家人和辅导员,也许是你的同龄人,或者你可能几乎没有得到任何帮助。list_3 中的每个元素都是一个包含多个句子的字符串,列表中有五个元素。
    • 非常感谢,这是正确答案,感谢您的帮助。
    【解决方案2】:

    假设句子用一个空格分隔,您可以使用re.findall 和以下正则表达式。

    r'(?m)(?<!^)(?<![.?!] )[A-Z][A-Za-z]*'
    

    Start your engine! | Python code

    Python 的正则表达式引擎执行以下操作。

    (?m)         : set multiline mode so that ^ and $ match the beginning
                   and the end of a line
    (?<!^)       : negative lookbehind asserts current location is not
                   at the beginning of a line
    (?<![.?!] )  : negative lookbehind asserts current location is not
                   preceded by '.', '?' or '!', followed by a space
    [A-Z]        : match an uppercase letter
    [A-Za-z]*    : match 1+ letters
    

    如果句子可以用一两个空格分隔,则在(?&lt;![.?!] ) 之后插入否定的lookbehind (?&lt;![.?!] )

    如果使用 PyPI 正则表达式模块,可以使用可变长度的lookbehind (?&lt;![.?!] +)

    【讨论】:

      【解决方案3】:

      据我了解,您的列表如下:

      list_3 = [
        'First sentence. Another Sentence',
        'And yet one another. Sentence',
      ]
      

      您正在迭代列表,但每次迭代都会覆盖 test 变量,因此您的结果不正确。您要么必须在附加变量中累积结果,要么在每次迭代时立即打印它:

      acc = []
      for item in list_3:
        acc.extend(re.findall(regexp, item))
      print(acc)
      

      for item in list_3:
        print(re.findall(regexp, item))
      

      至于正则表达式,忽略句子中的第一个单词,你可以使用

      re.findall(r'(?<!\A)(?<!\.)\s+[A-Z]\w+', s) 
      
      • (?&lt;!\A) - 不是字符串的开头
      • (?&lt;!\.) - 不是点后的第一个单词
      • \s+ - 点后的可选空格。

      你会收到以空格为前缀的单词,所以这是最后一个例子:

      acc = []
      for item in list_3:
        words = [w.strip() for w in re.findall(r'(?<!\A)(?<!\.)\s+[A-Z]\w+', item)]
        acc.extend(words)
      print(acc)
      

      【讨论】:

      • 请注意,您不仅要匹配大写单词,还要匹配它们前面的空格(当然可以轻松删除)。
      【解决方案4】:

      因为我真的很喜欢正则表达式,所以试试这个:

      #!/bin/python3
      import re
      
      PATTERN = re.compile(r'[A-Z][A-Za-z0-9]*')
      
      all_sentences = [
          "My House! is small",
          "Does Annie like Cats???"
      ]
      
      def flat_list(sentences):
          for sentence in sentences:
              yield from PATTERN.findall(sentence)
      
      upper_words = list(flat_list(all_sentences))
      print(upper_words)
      
      # Result: ['My', 'House', 'Does', 'Annie', 'Cats']
      

      【讨论】:

        猜你喜欢
        • 2021-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-22
        • 2022-01-22
        • 1970-01-01
        相关资源
        最近更新 更多