Подтвердить что ты не робот

Почему Ruby/[[: punct:]]/пропускают некоторые знаки препинания?

Ruby /[[:punct:]]/ должен соответствовать всем "символам пунктуации". Согласно Wikipedia, это означает /[\]\[!"#$%&'()*+,./:;<=>[email protected]\^_`{|}~-]/ по стандарту POSIX.

Он соответствует: -[]\;',./[email protected]#%&*()_{}::"?.

Однако он не соответствует: =`~$^+|<> (по крайней мере, в ruby ​​1.9.3p194).

Что дает?

4b9b3361

Ответ 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 

Там более длинный список категорий здесь.