Python regex: re.sub () не обрабатывает правильно акцентированные символы, в противоположность re.compile (). Sub () [duplicate]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

14
задан jonrsharpe 13 April 2015 в 09:44
поделиться

2 ответа

Как Padraic Cunningham выяснил , это на самом деле не ошибка.

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


недавнее изменение (где-то между 3.4.1 и 3.4.3 и между 2.7.3 и 2.7.8), которое влияет на это. Перед этим изменением вы не сможете даже скомпилировать этот шаблон без повышения OverflowError.

Что еще более важно, почему вы используете re.L? Механизм re.L не означает «использовать правила Юникода для моей локали», это означает «использовать некоторые неуказанные правила, отличные от Юникода, которые действительно имеют смысл только для латинских производных локалей и могут работать неправильно на Windows». Или, как , docs положил его:

Задает \w, \W, \b, \B, \s и \S зависимые по текущему языку. Использование этого флага не рекомендуется, так как языковой механизм очень ненадежный и он обрабатывает только одну «культуру» в любой момент; вместо этого вы должны использовать Unicode-сопоставление, которое по умолчанию используется в шаблонах Python 3 для Unicode (str).

См. bug # 22407 и связанный поток python-dev для недавнего обсуждения этого вопроса.

И если я удалю флаг re.L, теперь код теперь компилируется просто отлично на 3.4.1. (Я также получаю «правильные» результаты как на 3.4.1, так и на 3.4.3, но это просто совпадение: теперь я намеренно не передаю винтовой флаг и ввинчиваю его в первую версию и все равно случайно не передаю винтовой флаг и завинчивание его во втором, так что они совпадают ...)

Итак, даже если это была ошибка, есть хороший шанс, что он будет закрыт WONTFIX. Разрешение для # 22407 состояло в том, чтобы осудить re.L для шаблонов не bytes в 3.5 и удалить его в 3.6, поэтому я сомневаюсь, что кто-то позаботится об исправлении ошибок с ним сейчас. (Не говоря уже о том, что сам re теоретически уходит в пользу regex в течение одного из этих десятилетий ... и IIRC regex также не одобрял флаг L, если вы не используете bytes и re -совместимый режим.)

14
ответ дан Community 20 August 2018 в 07:51
поделиться
  • 1
    Спасибо за помощь. Неверный порядок аргументов в re.sub() вызвал разные результаты между re.sub() и regex.sub() и противоречивым флагом re.L, что не соответствовал шаблону. Это плохое совпадение смутило меня, и ваши объяснения касались моей головной боли. – Vaclav 13 April 2015 в 12:23

Последний аргумент в компиляции - flags, если вы действительно используете flags=flags в re.sub, вы увидите одно и то же поведение:

compiled = re.compile(pattern, flags)
print(compiled)
text = 'Poplatníkem daně z pozemků je vlastník pozemku'
mark = r'**\1**' # wrap 1st matching group in double stars

r = re.sub(pattern, mark, text, flags=flags)

Четвертый аргумент re.sub count, поэтому вы видите разницу.

re.sub (pattern, repl, string, count = 0, flags = 0)

re.compile (pattern , flags = 0)

10
ответ дан Padraic Cunningham 20 August 2018 в 07:51
поделиться
  • 1
    Отличная добыча! Но описание немного запутанно. Он уже знает, что большой аргумент в compile есть flags; проблема в том, что четвертый аргумент sub равен not flags, это count. Итак, он эффективно проходит count=6, flags=0. (И поэтому вы всегда должны использовать аргументы ключевых слов, когда их больше, чем несколько.) – abarnert 13 April 2015 в 10:14
  • 2
    @abarnert, да забыл добавить эту часть. Приветствия. – Padraic Cunningham 13 April 2015 в 10:16
  • 3
    Самое смешное, что на самом деле у него две ошибки, отменяющие друг друга. Это первый, где он случайно пропускает flags как count, который возвращает результат, который он хочет, потому что это предотвращает нарушение флага re.L ... – abarnert 13 April 2015 в 10:23
  • 4
    Ой, как я не заметил этого! Заказ таких параметров выглядит несколько глупо, по этой причине. – jonrsharpe 13 April 2015 в 10:38
  • 5
    @jonrsharpe: IIRC, flags не было в исходном модуле (s)re. Когда он был добавлен в 2.3 или около того, единственное, что нужно сделать, это добавить его к каждой функции после всех существующих аргументов. (Ну, разумная вещь real - сделать ее параметром только для ключевого слова, но тогда никто не думал об этом.) – abarnert 13 April 2015 в 12:29
Другие вопросы по тегам:

Похожие вопросы: