【问题标题】:How to strip a certain piece of text from each line of a text file?如何从文本文件的每一行中删除一段文本?
【发布时间】:2022-01-27 07:02:03
【问题描述】:

我已经下载了带有英语-德语句子对的制表符分隔的 tatoeba 数据集,以在其上训练 NMT 模型。不幸的是,每一行都以各种附加信息结尾:

Go. Geh.    CC-BY 2.0 (France) Attribution: tatoeba.org #2877272 (CM) & #8597805 (Roujin)
Hi. Hallo!  CC-BY 2.0 (France) Attribution: tatoeba.org #538123 (CM) & #380701 (cburgmer)

如何去除文本文件中每一行第二句之后的部分?

我尝试在 python 中这样做:

for line in text:
  split = line.split('CC-BY', 1)
  line = split[0]

...但这没有用。我正在寻找的是一个看起来像这样的文件:

Go. Geh.
Hi. Hallo!

如有任何帮助,我将不胜感激:)

【问题讨论】:

  • 在这里拆分对我来说似乎不是合乎逻辑的事情,我只会将.find() 与字符串索引/切片一起使用,例如:segment = line[:line.find('CC-BY')].rstrip()
  • 什么不是特别有效?如果我在 for 循环的每次迭代结束时执行 print(line),我会得到所需的输出。您是在问如何将提取的行输出到文件中?

标签: python text strip machine-translation


【解决方案1】:

使用split的想法是正确的,但是在for循环中直接以这种方式赋值不会改变列表元素。

split 已经是一个内置方法的名称时,您还应该避免使用它作为变量名。

列表推导可以完成这项工作:

new_lines = [line.split('CC-BY', 1)[0].strip() for line in text]

添加strip 是因为您可能希望删除每行末尾的多余空格。


将输入文本保存为text.txt,以下代码:

with open("text.txt", encoding="utf8") as f:
    text = f.read().splitlines()

new_lines = [line.split('CC-BY', 1)[0].strip() for line in text]

for line in new_lines:
    print(line)

给出输出:

Go. Geh.
Hi. Hallo!

【讨论】:

  • 感谢您的评论,不幸的是我无法使代码工作。我运行它,结果看起来像这样: ['G', 'o', '.', '', 'G', 'e', 'h', '.', '', 'C', 'C', '-', 'B', 'Y', '', '2', '.', '0', '', '(', 'F', 'r', 'a', 'n'、'c'、'e'、')'、''、'A'、't'、't'、'r'、'i'、'b'、'u'、't' , 'i', 'o', 'n', ......]
  • 您可能没有将输入分成几行。请使用完整代码查看上面编辑的答案。
【解决方案2】:

我喜欢 Python,但我不会在 Python 中这样做。您可以使用bash 对前 2 列进行切片:

cut -f1 -f2 tatoeba.en.de.tsv

(假设文件名为 tatoeba.en.de.tsv。)

将其通过管道传输到文件中:

cut -f1 -f2 tatoeba.en.de.tsv > tatoeba.en.de.stripped.tsv

相对于朴素的 Python 方法的优势:

  • cut 更易于使用、更具可读性且代码更少。
  • cut 不会将整个文件加载到内存中,因此它可以处理非常大的文件。
  • > 只会将输出写入文件,而不是错误消息。

选项卡是核心 bash 实用程序中的一等公民这一事实是选择 TSV for machine translation data 的一个重要原因。


如果您真的想在 Python 中执行此操作,以便它适用于任何 Tatoeba 文件的内容或大小:

  • 在制表符上拆分并使用slice 或切片表示法,CC-BY 之类的值上拆分并剥离
  • 从迭代器中读取,将所有行读入对象中
filename = sys.argv[1] # Pass the name of the file
with open(filename, 'r') as f:
    for line in f:
        source, target = line.split('\t')[:1] # "slice" the first 2 columns
        print(source, target, sep='\t')

【讨论】:

  • 感谢您的回复——您的方法似乎是解决此任务的更有效方式。但是,来自 tatoeba 的数据是以 .txt 格式而不是 .tsv 格式提供的,因此在我有限的编程知识的情况下,按照您上面评论者建议的方式进行操作对我来说更容易,这就是他收到复选标记的原因。
  • @Zwiebak Tatoeba 文件实际上是 TSV 文件 - 即列分隔符是制表符 - 无论使用什么文件扩展名。您可以将机器上的文件扩展名从 .txt 更改为 .tsv,或者更改上面代码中的文件名以匹配您拥有的文件。
  • 好的,很高兴知道!谢谢你的帮助:)
猜你喜欢
  • 1970-01-01
  • 2021-06-20
  • 2013-05-13
  • 2023-02-08
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多