【问题标题】:Best way to replace sentences/paragraphs with a string in python在python中用字符串替换句子/段落的最佳方法
【发布时间】:2018-11-19 10:08:25
【问题描述】:

如何将文本文件中的所有句子和段落替换为 <string> 标记?

我想保持文本文档中的间距、制表符和列表不变:

示例输入:

Clause 1:

  a) detail 1. some more about detail 1. Here is more information about this paragraph right here. There is more information that we think sometimes.

  b) detail 2. some more about detail 2. and some more..

示例输出:

<string>

  a) <string>

  b) <string>

【问题讨论】:

标签: python text nlp text-processing text-parsing


【解决方案1】:

我不知道这是否是最好的方式,但它相当简单,并且易于修改。它处理您的问题陈述中的示例,以及您评论中的大部分示例。

import sys, re

text = sys.stdin.read()

# A pattern expressing the parts of the input that we want to preserve:
keeper_pattern = r'''(?x)  # verbose format

    (   # We put parens around the whole pattern
        # (and use ?: for subgroups)
        # so that when we use it as the splitter-pattern for re.split(),
        # the result contains one string for each occurrence of the pattern
        # (in addition to the usual between-splitter strings).

                    # The main thing we want to keep is paragraph-separators,
                    # and the 'lead' of the line that follows a para-sep:
                    #
        \n{2,}      # two or more newlines, followed by
        \x20*       # optional indentation (zero or more spaces), followed by
        (?:         # an optional item-marker, which is
          (?:         #   either
            \d+ \.    #       digits followed by a dot,
            |         #   or
            [a-z] \)  #       a letter followed by a right-paren,
          )           #   followed by
          \x20+       #   one or more spaces.
        )?

        |
                    # The other thing we want to keep is
                    # item-markers within paragraphs:
                    #
        \( i+ \)    # a lower-case Roman numeral between parens
                    # (generalize as necessary)
    )
'''

for (i, chunk) in enumerate(re.split(keeper_pattern, text)):

    # In the result of re.split(),
    # the splitters (keepers) will be in the odd positions.
    is_keeper = (i % 2 == 1)

    if is_keeper:
        if chunk.startswith('\n'):
            # paragraph-separator etc
            replacement = chunk
        else:
            # within-para item-marker
            replacement = ' ' + chunk + ' '
    else:
        if chunk == '':
            # (happens if two keepers are adjacent)
            replacement = ''
        else:
            # everything else
            replacement = '<string>'

    sys.stdout.write(replacement)

【讨论】:

  • 谢谢,这就是我要找的,它不能处理所有的情况,但我会添加更多,看看是否有可能解决所有这些情况
  • 实际上,我发现我的输出为一段句子返回多个 标签,即使我只希望一个标签代表所有这些标签。我将如何改变这一点?我已经更新了输入/输出,使其更加清晰
  • 当我在您修改后的示例输入上运行上述代码时,我得到了您的示例输出,因此您所描述的行为一定是由于您对代码所做的更改。
【解决方案2】:

使用 re 模块:

>>> import re
>>> text = 'Aaaaaaaaaaaaaaa,     to replace!\n to replace?\n\thelll34234ooooo'
>>> re.sub(r'(\w+)', '<string>', text)

它输出:

>>> '<string>,     <string> <string>!\n <string> <string>?\n\t<string>'

re.sub 表示:用&lt;string&gt; 替换text 中出现的所有(\w+)

对于文件:

main.py:

import re

with open('main.py', 'r') as input:
    text = input.read()
    print(text, '\n\n----------------\n')
    print(re.sub(r'(\w+)', '<string>', text))

输出:

import re

with open('main.py', 'r') as input:
    text = input.read()
    print(text, '\n\n----------------\n')
    print(re.sub(r'(\w+)', '<string>', text)) 

----------------

<string> <string>

<string> <string>('<string>.<string>', '<string>') <string> <string>:
    <string> = <string>.<string>()
    <string>(<string>, '\<string>\<string>----------------\<string>')
    <string>(<string>.<string>(<string>'(\<string>+)', '<<string>>', 
<string>))

【讨论】:

  • 感谢@Persi,但我希望用 替换整个句子或段落,而不是每个单词
猜你喜欢
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2016-06-21
相关资源
最近更新 更多