Лучший способ заменить предложения / абзацы строкой в ​​Python - PullRequest
0 голосов
/ 09 июня 2018

Как бы заменить все предложения и абзацы тегом <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>

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Я не знаю, является ли это лучшим способом, но это довольно просто и легко изменить.Он обрабатывает пример в вашей постановке задачи, а также большую часть примера из вашего комментария.

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)
0 голосов
/ 09 июня 2018

Использовать 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 означает: заменять каждое вхождение (\w+) в text с <string>.

Для файла:

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>))
...