Почему Ruby/[[: punct:]]/пропускают некоторые знаки препинания?
Ruby /[[:punct:]]/
должен соответствовать всем "символам пунктуации". Согласно Wikipedia, это означает /[\]\[!"#$%&'()*+,./:;<=>[email protected]\^_`{|}~-]/
по стандарту POSIX.
Он соответствует: -[]\;',./[email protected]#%&*()_{}::"?
.
Однако он не соответствует: =`~$^+|<>
(по крайней мере, в ruby 1.9.3p194).
Что дает?
Ответы
Ответ 1
Класс символов пунктуации определяется локалью. Открытая группа Определение LC_TYPE для punct говорит:
Определите символы, которые будут классифицированы как знаки пунктуации. В локали POSIX не включаются ни <space>
, ни любые символы в классах alpha, digit или cntrl. В файле определения локали не указывается ни один символ для ключевых слов: верхний, нижний, альфа, цифра, cntrl, xdigit или как указано.
В основном, он определяет, как punct может быть определен путем исключения других классов символов, но он фактически не определяет символы пунктуации напрямую - это задание локали.
Я не мог найти канонической ссылки на то, что находится в каждой локали. Может, кто-то еще знает. Тем временем вы можете найти LC_TYPE, который соответствует классу символов punct, который вы хотите, или просто указать класс напрямую.
Ответ 2
Символ "больше" относится к категории "Символ, математика", а не к категории пунктуации. Это можно увидеть, если принудительно задать кодировку регулярных выражений в кодировке UTF-8 (по умолчанию используется кодировка источника, и, предположительно, ваш источник закодирован в кодировке UTF-8, в то время как мой источник по умолчанию - что-то другое):
2.1.2 :004 > /[[:punct:]]/u =~ '<'
=> nil
2.1.2 :005 > /[[:punct:]]/ =~ '<'
=> 0
Если вы принудительно зададите регулярное выражение в кодировке ASCII (/n - здесь больше опций), вы увидите, что оно категоризирует "<" в пункту, что, я думаю, именно то, что вам нужно. Однако это, вероятно, вызовет проблемы, если ваш источник содержит символы вне подмножества ASCII UTF-8.
2.1.2 :009 > /[[:punct:]]/n =~ '<'
=> 0
Лучшим решением было бы использовать категорию "Символ" вместо этого в своем регулярном выражении вместо категории "пункт", что соответствует "<" в кодировке UTF-8:
2.1.2 :012 > /\p{S}/u =~ '<'
=> 0
Там более длинный список категорий здесь.