Regex ведет себя по-разному для одной и той же входной строки - PullRequest
2 голосов
/ 09 февраля 2020

Я пытаюсь получить страницу в формате PDF с определенной строкой и строкой:

"отчет о прибылях и убытках"

, и я пытаюсь выполнить sh это используя следующее регулярное выражение:

re.search('statement of profit or loss', text, re.IGNORECASE)

Но даже если страница содержала эту строку «отчет о прибылях и убытках», регулярное выражение вернуло None. При дальнейшем изучении документа я обнаружил, что символы «fi» в «прибыли», как написано в документе, более перегружены. Когда я скопировал его из документа и вставил в свой код, он работал нормально.

Итак, если я скопирую «отчет о прибылях и убытках» из документа и вставлю его в re.search () в моем коде, это работает отлично. Но если я напишу «отчет о прибылях и убытках» вручную в своем коде, re.search () не вернет ничего. Как я могу избежать этого поведения?

1 Ответ

3 голосов
/ 09 февраля 2020

«перегруженные» символы, скопированные из вашего PDF-файла, на самом деле являются одиночными символами: «фи лигатура» U + FB01: .

либо это было введено как таковое в исходном документе, или механизм набора текста, который использовался для создания PDF, заменил комбинацию f+i на fi.

Объединение двух или более символов в один глиф является довольно обычная операция для «хорошего набора текста», и не ограничивается fi, fl, ff и fj, хотя это наиболее часто используемые комбинации. (Это потому, что в некоторых шрифтах длинный свес глифа f резко касается или перекрывает следующий символ.) На самом деле, вы можете иметь любое количество лигатур; некоторые шрифты Adobe используют одну лигатуру для Th.

Обычно это не проблема с извлечением текста, поскольку в PDF можно указать, что определенные глифы должны быть декодированы как строка символов - оригинальные символы. Так что, возможно, ваш PDF не содержит такого определения, или механизм набора не беспокоил, потому что один символ является допустимым символом Unicode сам по себе (хотя настоятельно рекомендуется не использовать его).

Вы можете обойти это, явно очистив текстовые строки перед дальнейшей обработкой:

text = text.replace('fi', 'fi')

- повторите это для других проблемных c лигатур, имеющих код Unicode: , , , (возможно, я пропустил еще немного).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...