Python - 从没有正则表达式的段落中的引号中提取单词

Python - Extract words from quotes from a paragraph without regex

我将以下段落作为 .txt 文件的输入:

... Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem urna. Pellentesque elementum "turpi'" est, "in fermentum diam auctor aliquam!". Morbi rhoncus erat ipsum, eu "tristique" ...

这里是 Python 字符串:

'Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem urna. Pellentesque elementum "turpi" est, "in fermentum diam auctor aliquam!". Morbi rhoncus erat ipsum, eu "tristique"'

我想创建一个仅包含引用短语的列表,并将引号内的单词隔离为列表(以空格分隔)。

输出:

['ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.', 'turpi'', 'in', 'fermentum', 'diam', 'auctor', 'aliquam!', 'tristique']

我的思考过程一直是读入文件,然后以某种方式用引号分隔段落,但我似乎无法找到让 'split()' 以我想要的方式工作的方法。我觉得这可以通过最少的循环和使用 split() 作为组织数据的方式来完成,而无需使用 re、shlex、csv 或其他导入模块。

我什至考虑过将定界符添加回列表,然后 'cleaning' 列表。但即使这样也感觉有点复杂。

下面的代码为数组中的每一项都添加了双引号,这不是我想要的。只是我觉得我可以在使用 split() 后跟踪报价的一种方式。

with open(input_file, "r") as read_file:
     for line in read_file:
          quotes = ['"' + i + '"' for i in line.split('"') if i]

这里有两种可能的方法:

desired = [
    'ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.',
    'turpi\'', 'in', 'fermentum', 'diam', 'auctor', 'aliquam!', 'tristique'
    ]

text = """
Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem
urna. Pellentesque elementum "turpi'" est, "in fermentum diam auctor aliquam!".
Morbi rhoncus erat ipsum, eu "tristique"
"""

def extract_quoted(text):
    words = []
    next_pos = -1
    while True:
        try:
            pos = text.index('"', next_pos + 1)
        except ValueError:
            break
        try:
            next_pos = text.index('"', pos + 1)
        except ValueError as e:
            raise ValueError("mismatched quotes") from e
        quoted_segment = text[pos + 1:next_pos]
        words.extend(quoted_segment.split())
    return words

def split_only(text):
    return [word for chunk in text.split('"')[1::2] for word in chunk.split()]

if __name__ == "__main__":
    print(extract_quoted(text) == desired)
    print(split_only(text) == desired)

第一个更明确地说明文本是如何呈现的 "parsed",而第二个可能更华丽的基于单线分割 您正在寻找的方法。

我试过这个:

a = """Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem urna. Pellentesque elementum "turpi'" est, "in fermentum diam auctor aliquam!". Morbi rhoncus erat ipsum, eu "tristique" """
in_quote = 0
res = []
word = ''

for i in a:
    if i == '"':
        in_quote = 1 - in_quote
        if word:
            res+=[word]
            word = ''
    elif in_quote:
        if i == ' ':
            res+=[word]
            word = ''
        else:
            word+=i
print(res)

从我的评论中复制:

使用 " 作为分隔符拆分后,您可以简单地提取列表的所有奇数索引元素。然后,正常拆分这些元素(使用空格分隔符)并将列表连接在一起。

示例:

text = """Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem urna. Pellentesque elementum "turpi'" est, "in fermentum diam auctor aliquam!". Morbi rhoncus erat ipsum, eu "tristique" """

text_split_by_quotes = text.split('"')
# get the odd-indexed elements (here's one way to do it):
text_in_quotes = text_split_by_quotes[1::2]
# split each normally (by whitespace) and flatten the list (here's one way to do it):
ans = []
for text in text_in_quotes:
    ans.extend(text.split())
# print answer
print(ans)

>>> ['ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.', "turpi'", 'in', 'fermentum', 'diam', 'auctor', 'aliquam!', 'tristique'] 

检查这个逻辑,基本上在拆分之后你可以简单地 select 每个第二个索引,因为你开始时你的文本中没有双引号。

text = 'Lorem "ipsum dolor sit amet, consectetur adipiscing elit.". Praesent non sem urna. Pellentesque elementum "turpi" est, "in fermentum diam auctor aliquam!". Morbi rhoncus erat ipsum, eu "tristique"'
print(text)

split_text = text.split('"')
print(split_text)

new_split_text = [elem for i,elem in enumerate(split_text) if i%2 == 1]
print(new_split_text)

如果你想要一个衬垫:

new_split_text = [elem for i,elem in enumerate(text.split('"')) if i%2 == 1]

输出:

['ipsum dolor sit amet, consectetur adipiscing elit.', 'turpi', 'in fermentum diam auctor aliquam!', 'tristique']