Строка Python: извлеките дублированную и случайно объединенную подстроку

Пример дублированной и объединенной строки:

16.01068.0%0 8p%.a .p .a.

Желаемая подстрока для извлечения:

16.008% p.a.

Более полный пример:

CCoonnttiinnggeenntt CCoouuppoonn 16.01068.0%0 8p%.a .p (.Ma.o (nMtholyn)thly)

Желаемая подстрока:

Contingent Coupon 16.008% p.a. (Monthly)

Моя проблема в том, что когда исходная подстрока уже содержит повторяющиеся символы (например, два 0 в 16.008), моя текущая функция иногда сохраняет неправильный повторяющийся символ (давая неправильный результат 16.080).

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

folen gateis 22.07.2024 19:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете думать об этом явлении как о дублирующейся строке, отстающей от основной строки на некоторое количество символов. Поскольку дублирующая строка с индексом i всегда должна соответствовать основной строке с индексом i, вы можете использовать эту характеристику как способ определить, принадлежит ли входящий символ дублирующей строке или основной строке. Чтобы обрабатывать случаи, когда правильная строка содержит два одинаковых последовательных символа и встречается второй из них, вы можете использовать алгоритм поиска с возвратом, чтобы найти путь, ведущий к соответствующей повторяющейся строке.

Обратите внимание, что дублирующиеся символы, скорее всего, являются результатом эмуляции жирного шрифта, но поскольку в дублирующихся пробелах ничего не видно, они, к сожалению, идентифицируются сканером PDF как один пробел. В качестве обходного пути вы можете искусственно заменить каждый пробел во входных данных двумя пробелами, а затем заменить любые два последовательных пробела одним пробелом для вывода. Также обратите внимание, что в вашей входной строке может отсутствовать конечный пробел, поскольку сканер не может идентифицировать его без видимой границы. Вы можете искусственно добавить конечный пробел к входным данным и впоследствии удалить конечные пробелы:

def dedupe(string):
    def _dedupe(pos, dupe):
        if pos == size:
            return dupe == half
        char = string[pos]
        if (dupe < len(output) and output[dupe] == char and
                _dedupe(pos + 1, dupe + 1)):
            return True
        output.append(char)
        if _dedupe(pos + 1, dupe):
            return True
        output.pop()

    string = (string + ' ').replace(' ', '  ')
    size = len(string)
    half = size // 2
    output = []
    if _dedupe(0, 0):
        return ''.join(output).replace('  ', ' ').rstrip()
    raise ValueError('No matching duplicate found.')

так что:

print(dedupe(
"CCoonnttiinnggeenntt CCoouuppoonn 16.01068.0%0 8p%.a .p (.Ma.o (nMtholyn)thly)"
))

выходы:

Contingent Coupon 16.008% p.a. (Monthly)

Демо здесь

Спасибо. Кстати, пробелов нет, строка, возвращаемая пакетом pdfplumber, точно такая, как я ее ввел. Но макет исходной записи таблицы PDF, отсканированной pdfplumber, запутал алгоритм. В моем описании проблемы ошибочно предполагалось, что путаница носит более детерминированный характер, чем она есть на самом деле.

Big Data Newbie 23.07.2024 07:33

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

blhsing 23.07.2024 07:42

Да, я так считаю.

Big Data Newbie 23.07.2024 07:44

Ну, тогда я обновил свой ответ, указав обходной путь.

blhsing 23.07.2024 07:52

Я считаю, что решение должно быть более сложным, чем ваша функция. Вот пример: «11,7151%.7 5%» (что при дедупликации должно быть «11,75%». Без какого-либо предпросмотра невозможно различить следующие два случая: А) первый символ «1» является частью основная строка, второй символ «1» является дубликатом, B) первый и второй символы «1» являются частью основной строки. Кажется, что эти два случая можно различить только тогда, когда мы достигнем третьей «1» и обнаружим, что соответствующий повторяющийся символ имеет индекс меньше, чем предыдущие соответствующие повторяющиеся символы.

Big Data Newbie 24.07.2024 00:40

Затем я обновил ответ с помощью алгоритма возврата.

blhsing 24.07.2024 06:20

Еще раз спасибо! Я сам писал алгоритм возврата. Ты намного быстрее, чем я.

Big Data Newbie 24.07.2024 08:02

Зачем вы добавляете лишний пробел в конце строки?

Big Data Newbie 24.07.2024 09:02

Пожалуйста. Как отмечено в обновленном ответе, в вашем вводе, по-видимому, отсутствует конечный пробел, предположительно потому, что сканер не может идентифицировать его без видимой границы, поэтому в качестве обходного пути мы можем добавить конечный пробел к вводу и впоследствии удалить конечные пробелы.

blhsing 24.07.2024 10:48

Другие вопросы по теме