Соответствие регулярного выражения недопустимым символам Юникода - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть такие строки:
ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ
и я хочу отфильтровать все эти недопустимые символы, начинающиеся с косой черты, что я пытаюсь сделать с регулярным выражением в Python.

Это работает так:

re.sub(r",\u0f6e,", r",deleted,", s)

Но не так:

re.sub(r",\.{5},", r",deleted,", s)

Это должно работать в соответствии с http://pythex.org,, поэтому я думаю, это потому, что они недопустимые символы? Как я могу сопоставить их?

Редактировать: @metatoaster сказал, что мой вопрос неоднозначен: Кажется, проблема возникает из-за того, что входная строка s не является необработанной строкой.

>>> s = ' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Кажется, у вас есть строка с неопределенными кодовыми точками Юникода. \u0f6e - это единичная кодовая точка , представленная в виде escape-кода. Пример:

>>> s = 'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> s
'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> print(s)
ꐊ,ꀵ,཮,ⴗ,ꦚ,⵵,ꢯ,⾌,꥽,⩱,ㇴ,⵮,鼺, Ꞁ

Обратите внимание, что при печати строки символ отображается в виде неопределенного поля. Он отображается как escape-код для отладки. Эти кодовые точки имеют несколько общих черт. Согласно базе данных Unicode, они являются кодовыми точками категории C (контроль). У них также нет имен. Быстрый способ фильтрации:

>>> ''.join(['deleted' if ud.category(c)[0] == 'C' else c for c in s])
'ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,deletedꞀ'
0 голосов
/ 09 ноября 2018

Я не вижу, как бы сработал ваш первый оператор re.sub, если бы ваша строка была действительно определена как есть.

>>> s = r' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)                                        
' ꐊ,ꀵ,\\u0f6e,ⴗ,ꦚ,\\u2d75,ꢯ,⾌,\\ua97d,⩱,ㇴ,\\u2d6e,鼺,\\x00Ꞁ'                

Обратите внимание, как остается первый r'\u0f6e'. В регулярных выражениях символ \ также является специальным, поэтому его также следует экранировать. Это можно сделать с помощью \\. Теперь попробуйте:

>>> re.sub(r",\\u0f6e,", r",deleted,", s)                                       
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\\u2d75,ꢯ,⾌,\\ua97d,⩱,ㇴ,\\u2d6e,鼺,\\x00Ꞁ'                

Чтобы соответствовать действительному выражению и не больше, чем необходимо, обратите внимание, что последовательность \\u содержит ровно 4 последовательных символа между 0-9 и a-f. Вместо того, чтобы пытаться сопоставить любые 5 символов, будьте более конкретны, например:

>>> re.sub(r",\\u[0-9a-f]+,", r",deleted,", s)                                  
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,\\x00Ꞁ'                

Обратите внимание, что весь этот ответ предполагает, что предоставленная вами информация верна, а escape-последовательности на самом деле являются символом обратной косой черты. Было бы полезно обновить ваш вопрос, включив в него эти фрагменты кода, как у меня здесь, чтобы быть менее двусмысленным в отношении того, что делается (поскольку мы можем скопировать и вставить ваш код и запустить его, чтобы увидеть, что пошло не так, и мы также можем исправить это более подробно). легко).

...