Как указать диапазон символов юникода

19

Как указать диапазон символов Unicode из ' ' (пробел) в \u00D7FF ?

У меня есть регулярное выражение, например r'[\u0020-\u00D7FF]' , и оно не будет компилироваться, говоря, что это плохой диапазон. Я новичок в регулярных выражениях Unicode, поэтому раньше у меня не было этой проблемы.

Есть ли способ сделать это компиляцию или регулярное выражение, которое я забыл или еще не узнал?

    
задан spig 01.10.2010 в 03:18
источник
  • Он отлично компилируется здесь (2.6.5) –  NullUserException 01.10.2010 в 03:23
  • Вы правы - это компиляция - я предположил, что это часть регулярного выражения, над которым я работал, у которого были проблемы. Я отправлю часть, которая вызывает у меня проблемы. –  spig 01.10.2010 в 03:25

2 ответа

25

Синтаксис вашего юникодного диапазона не будет делать то, что вы ожидаете.

  1. Необработанная строка r'' предотвращает синтаксический анализ \u escapes, и механизм regex этого не сделает. Единственный диапазон в этом наборе: [0-\] :

    >>> re.compile(r'[\u0020-\u00d7ff]', re.DEBUG)
    in
      literal 117
      literal 48
      literal 48
      literal 50
      range (48, 117)
      literal 48
      literal 48
      literal 100
      literal 55
      literal 102
      literal 102
    
  2. Создание литерала Unicode вызывает анализ \u при оставлении других обратных косых черт (хотя это не вызывает беспокойства), но ведущие нули испортили его. Синтаксис: \uxxxx или \Uxxxxxxxx , поэтому он анализируется как « \u00d7 , f , f ».

    >>> re.compile(ur'[\u0020-\u00d7ff]', re.DEBUG)
    in
      range (32, 215)
      literal 102
      literal 102
    
  3. Удаление начальных нулей или переход на \U0000d7ff будут исправлены:

    >>> re.compile(ur'[\u0020-\ud7ff]', re.DEBUG)
    in
      range (32, 55295)
    
ответ дан Josh Lee 01.10.2010 в 03:59
  • Большое спасибо - я понятия не имел о всех материалах Юникода. Таким образом, это должно быть 4 цифры с нижним регистром «u» и 8 с верхним регистром «U», правильно? –  spig 01.10.2010 в 04:36
  • Это правильно. –  Josh Lee 01.10.2010 в 05:54
  • Обратите внимание, что этот ответ сделан в контексте Python 2. В Python 3 нет разницы между примером r "example" и ur ". –  Flimm 22.01.2018 в 17:46
5

Если вы используете Python 2.x, вы должны убедиться, что вы указываете строку юникода (с помощью u '' или встроенного в Unicode):

>>> r = re.compile(u'[\u0020-\uD7FF]')
>>> r.search(u'foo \uD7F0 bar')
<_sre.SRE_Match object at 0xb7084950>
r.search(u' ')
<_sre.SRE_Match object at 0xb7084b48>

Используя исходные строки (как вы, с r ''), вы получаете строку (ascii), составленную «backstroke» + буквой «u» плюс число 0 плюс ...

    
ответ дан rbp 01.10.2010 в 03:33
  • Вам нужны символы '0', когда \ u не достаточно длинный, чтобы быть 4 длинными? Как в пространстве, у вас будет только \ u20, но вам придется писать \ u0020 ?, правильно? –  spig 01.10.2010 в 04:39
  • Я вижу, вы уже получили ответ, но да, это правильно :) –  rbp 04.10.2010 в 14:33
  • Как насчет полного Unicode? Например, готический блок работает от U + 10330 GOTHIC LETTER AHSA через U + 1034A GOTHIC LETTER NINE СТО, но также включает в себя следующие пять кодовых пунктов, в настоящее время неназванных? Как вы в Python выражаете, какие другие языки программирования позволяют вам использовать \ p {Gothic}, \ p {Script = Gothic}, \ p {InGothic} или \ p {Block = Gothic} для? Например, в Perl / \ pN / && / \ p {InGothic} / дает U + 10341 GOTHIC LETTER NINETY и U + 1034A GOTHIC LETTER NINE СТО. Однако это не работает на Python; почему нет? –  tchrist 02.11.2010 в 13:36
  • Если я правильно понял, вы можете использовать прописную букву U для больших кодовых точек, заполняя до 8 шестнадцатеричных цифр. Например, в вашем примере U + 10330 вы должны использовать u '\ U00010330' –  rbp 08.11.2010 в 22:38