Замена строки: многострочная, без учета регистра, со специальными символами - PullRequest
0 голосов
/ 08 мая 2020

Цель: для данной строки заменить каждое вхождение '<?xml version="1.0" encoding="utf-8"?>' и заглавных букв «двоюродных братьев» пустой строкой ''.

Решение string.replace() и / или re.sub() решение было бы отличным. Решение на основе модуля BeautifulSoup будет рассматриваться только в крайнем случае.

  1. Попытка на основе string.replace():

    s = '1:<?xml version="1.0" encoding="utf-8"?>\n2:<?xml version="1.0" encoding="UTF-8"?>'
    ## 1:<?xml version="1.0" encoding="utf-8"?>
    ## 2:<?xml version="1.0" encoding="UTF-8"?>
    h = '<?xml version="1.0" encoding="utf-8"?>'
    r = s.replace(h, '')
    ## 1:
    ## 2:<?xml version="1.0" encoding="UTF-8"?>
    

Проблема: не удаляет вхождения с форматированием в верхнем регистре, как в UTF-8 .

Попытка на основе re.sub():

import re
s = '1:<?xml version="1.0" encoding="utf-8"?>\n2:<?xml version="1.0" encoding="UTF-8"?>'
## 1:<?xml version="1.0" encoding="utf-8"?>
## 2:<?xml version="1.0" encoding="UTF-8"?>
h = '<?xml version="1.0" encoding="utf-8"?>'
r = re.sub(h, '', s, flags=re.IGNORECASE | re.MULTILINE)
## 1:<?xml version="1.0" encoding="utf-8"?>
## 2:<?xml version="1.0" encoding="UTF-8"?>

Проблема: вообще не работает. И все же работает более простой случай:

    import re
    s = '1:a\n2:A'
    ## 1:a
    ## 2:A
    h = 'a'
    r = re.sub(h, '', s, flags=re.IGNORECASE | re.MULTILINE)
    ## 1:
    ## 2:

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

Заголовок <?xml вводится в мой код парсером xml через модуль BeautifulSoup. У меня не было большого успеха с методами BeautifulSoup, например, .find_all() и .replace_with(). Я попробовал soup.decode_contents(), который работал в некоторых случаях, но не работал в других. Я не публикую примеры того, что я пробовал, потому что я бы предпочел не использовать модуль для конкретной задачи (у меня есть строка, я хочу вывести строку и не хочу, чтобы BeautifulSoup иначе изменял строка). С извинениями перед BS d ie -hards. ; -)

1 Ответ

1 голос
/ 08 мая 2020

Да, ? и . - специальные символы регулярных выражений. Вы можете экранировать их, например, re.escape():

import re
s = '1:<?xml version="1.0" encoding="utf-8"?>\n2:<?xml version="1.0" encoding="UTF-8"?>'
h = re.escape('<?xml version="1.0" encoding="utf-8"?>') # <-- put re.escape() around the string
r = re.sub(h, '', s, flags=re.IGNORECASE)               # <-- no need for RE.MULTILINE

print(r)

Prints (строка <?xml..?> заменяется):

1:
2:
...