Как выбрать между пробелами?
В документации по шаблону Oracle есть описание трех различных шаблонов для сопоставления пробелов:
- \ s
- \ Р {пробел}
- \ Р {javaWhitespace}
Мне интересно, в чем специфика каждого и как узнать, как правильно выбрать. Я только что заметил, что \p{javaWhitespace}
включить больше места типа.
3 ответа
Я бы предпочел использовать первое.
- Это компактно
- Это то же самое обозначение во многих других языках, а также в теории регулярных выражений
\p{javaWhitespace}
включаютFILE SEPARATOR
,GROUP SEPARATOR
и т.д... посмотри на это. Использование этого, когда они не нужны, может запутать кого-то другого.- В общем, я ожидаю, что другой программист будет знать, что
\s
в то время как я ожидаю, что они дважды проверить, каково точное определение\p{javaWhitespace}
, Вы не хотите этого, поскольку это уменьшает ясность кода и добавляет ненужную нагрузку во время отладки.
\s
это самый короткий и самый непереносимый параметр для указания пробела. Хотя портировать Java-код на другие языки редко, речь идет скорее о переносе знаний о синтаксисе одного механизма регулярных выражений в другой. Есть много движков регулярных выражений, использующих Perl-подобный синтаксис, поэтому разница в интерпретации для того же синтаксиса, как \s
смущает программистов.
Помимо пространства (ASCII 32), новая строка (\n
, ASCII 10), горизонтальная вкладка (\t
, ASCII 9), возврат каретки (\r
, ASCII 13) и форма подачи (\f
, ASCII 12), нет единого мнения о том, что является космическим персонажем.
Java, POSIX (ASCII): также включает вертикальную вкладку (ASCII 11). Кажется, что Java следует стандарту POSIX здесь.
JavaScript (Выпуск 5.1): Согласно спецификациям (дословно), помимо 5 распространенных, он включает в себя:
Unicode категория Zs (Разделитель / Пробел),
\u2028
(Разделитель строк),\u2029
(Разделитель параграфов). В основном это включает в себя все символы в категории Z (разделитель).На самом деле
\u2028
является единственным членом категории Zl (разделитель / линия), и\u2029
является единственным членом категории Zp (Разделитель / Абзац). По формулировке может быть возможно, что текущая версия спецификаций исключает какое-либо дальнейшее расширение на эти 2 категории.- Вертикальная вкладка
\v
- Порядок следования байтов ak a ZERO WIDTH NO-BREAK SPACE
\ufeff
Perl, PCRE (режим ASCII): вертикальная вкладка
\v
добавлен из Perl 5.18 в качестве эксперимента. До 5.18 он соответствует только 5 наиболее распространенным.Perl (режим Unicode): кроме 5 распространенных
- Unicode категория Z (разделитель)
- Вертикальная вкладка
\v
добавлен из Perl 5.18 в качестве эксперимента. - СЛЕДУЮЩАЯ ЛИНИЯ (NEL)
\u0085
- Монгольский гласный разделитель
\u180e
.NET (по умолчанию): кроме 5 распространенных
- Unicode категория Z (разделитель)
- Вертикальная вкладка
\v
- СЛЕДУЮЩАЯ ЛИНИЯ (NEL)
\u0085
Java (Unicode): из Java 7 класс Pattern включает новый флаг
UNICODE_CHARACTER_CLASS
что делает Предопределенные классы символов и классы символов POSIX соответствующими Техническому стандарту Unicode #18: Регулярное выражение Unicode. Когда флаг активен, предопределенный класс символов и соответствующий класс символов POSIX станут эквивалентными (соответствуют одному и тому же).Список символов такой же, как и в.NET.
Этого достаточно, чтобы свести с ума!
\p{Space}
является более "стабильной" опцией, так как она соответствует стандарту POSIX в режиме по умолчанию и техническому стандарту Unicode #18: регулярное выражение Unicode в UNICODE_CHARACTER_CLASS
,
Если вы используете символьный класс POSIX, POSIX-совместимая реализация будет иметь такое же поведение в режиме ASCII, а движки регулярных выражений Unicode, которые следуют этой рекомендации, будут иметь (почти) такое же поведение в режиме Unicode.
\s
а также \p{Space}
эквивалентны в Java независимо от флага. Если вы используете \s
в Java вы можете быть уверены, что следуете некоторому стандарту / рекомендации. Просто он не сообщает большинству программистов об этом факте.
\p{isJavaWhitespace}
сопоставлять пробелы в соответствии с определением Java. Название функции вводит в заблуждение.
Если у вас нет конкретной причины использовать другие варианты, я бы оставил это простым и использовать \s