Добрый день. У меня есть следующее регулярное выражение: <pre><code>("originalText":")(<i>)*([A-Za-z0-9\(\) ',.!?-]+)(</i>)*(","text":")(<)*([А-Яа-я0-9A-Za-z\(\) ,.!?-]+)(</i>\.|</i>)*",</code></pre> Я использую его для замены текста в файле, который содержит 10 259 006 символов и является словарем перевода игры. К сожалению, машинный перевод сделал так, что теги <code><i> </i></code> в русском тексте были повреждены или потеряны. Хотя данное регулярное выражение позволяет мне исправить большинство ошибок, оно также приводит к тому, что "здоровый" текст заменяется на себя же. Например, оно меняет: <pre><code>"originalText":"English text.","text":"Русский текст.",</code></pre> на <pre><code>"originalText":"English text.","text":"Русский текст.",</code></pre> Как мне можно исправить эту ситуацию? В частности, как исключить из поиска текст, в котором между <code>"originalText":"</code> и <code>","text":"</code> отсутствуют теги <code><i></code> или <code></i></code>? Привожу примеры для пояснения: <pre><code>"originalText":"English text.","text":"Русский текст.", - Этот текст должно пропустить "originalText":"<i>English text.","text":"Русский текст.", - Этот текст должно заменять "originalText":"English text.</i>","text":"Русский текст.", - Этот текст должно заменять "originalText":"<i>English text.</i>","text":"Русский текст.", - Этот текст должно заменять</code></pre> К сожалению, у меня недостаточно знаний, чтобы составить подобное регулярное выражение.
Чтобы ваше регулярное выражение заменяло только те строки, где присутствуют теги `<i>`, вам нужно добавить условие, которое позволит исключать строки, в которых нет этих тегов. Для этого можно использовать негативный просмотр (negative lookahead). Это позволит удостовериться, что между `originalText` и `text` есть хотя бы один из тегов `<i>`. Давайте попробуем изменить ваше регулярное выражение. Вот пример модифицированного регулярного выражения: ```regex ("originalText":")(?=(?:[^<]*<i>[^<]*</i>)*[^<]*$)(<i>)*([A-Za-z0-9\(\) ',.!?-]+)(</i>)*(","text":")(<)*([А-Яа-я0-9A-Za-z\(\) ,.!?-]+)(</i>\.|</i>)*", ``` Разберем изменения: - `(?=(?:[^<]*<i>[^<]*</i>)*[^<]*$)` – это позитивный просмотр, который проверяет, существуют ли в строке теги `<i>`. Он позволяет парсить только те строки, в которых присутствует хотя бы один тег. - Стараемся избегать изменений в основной структуре вашего выражения, чтобы не сломать прежнюю логику. Теперь ваше регулярное выражение будет работать только для строк, содержащих хотя бы один тег `<i>` между `"originalText":"` и `","text":"`. Для тестирования, просто подставьте строки в регулярное выражение и проверьте, как оно будет работать. Убедитесь, что вы правильно используете флаги режима (например, `re.MULTILINE`), если это необходимо. Если возникнут дополнительные вопросы или потребуется другая помощь, не стесняйтесь задавать!
Итак, у вас там файл в формате JSON. Это специальный машиночитаемый формат данных. Более правильное решение в вашем случае выглядит следующим образом:
Т.о. вся работа сводится к работе с однозначным и конкретным куском текста. У вас классический случай Проблемы XY .