Как выбрать шаблон пробела?
В документации Oracle Pattern представлено описание трех разных шаблонов для сопоставления пробелов:
- \s
- \р {Space}
- \р {javaWhitespace}
Мне интересно, какова специфика каждого и как знать, как правильно выбрать.
Я только заметил, что \p{javaWhitespace}
содержит больше типа пространства.
Ответы
Ответ 1
Я предпочел бы использовать первый.
- Он компактный
- Это то же обозначение на многих других языках, а также в теории regexp
-
\p{javaWhitespace}
включают FILE SEPARATOR
, GROUP SEPARATOR
и т.д. см. this. Использование этого, когда они не нужны, может смутить кого-то другого.
- В общем, я ожидал, что другой программист узнает, что
\s
, пока я ожидаю, что они дважды проведут проверку того, что является точным определением \p{javaWhitespace}
. Вы не хотите этого, поскольку это уменьшает ясность кода и добавляет ненужную нагрузку во время отладки.
Ответ 2
\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 category Zs (разделитель/пробел), \u2028
(разделитель строк), \u2029
(разделитель абзацев). Он в основном включает всех персонажей под категорией Z (разделитель).
Фактически \u2028
является единственным членом категории Zl (Separator/Line), а \u2029
является единственным членом категории Zp (разделитель/абзац). По формулировке, возможно, что текущая версия спецификаций исключает любое дальнейшее расширение для этих 2 категорий.
- Вертикальная вкладка
\v
- Байт-ордер Mark a.k.a. ПРОБЕЛ ПРОИЗВОЛЬНОГО ШИРИНА ZERO
\ufeff
-
Perl, PCRE (режим ASCII): вкладка Vertical \v
добавлена в Perl 5.18 в качестве эксперимента. До 5.18 он соответствует только 5 обычным.
-
Perl (режим Unicode): кроме 5 обычных
- Юникодная категория Z (разделитель)
- Вертикальная вкладка
\v
добавлена в Perl 5.18 в качестве эксперимента.
- СЛЕДУЮЩАЯ ЛИНИЯ (NEL)
\u0085
- СЕГАРАТОР МОНГОЛЬСКОГО ПОЛОСА
\u180e
-
. NET (по умолчанию): кроме 5 обычных
- Юникодная категория Z (разделитель)
- Вертикальная вкладка
\v
- СЛЕДУЮЩАЯ ЛИНИЯ (NEL)
\u0085
-
Java (Unicode): из Java 7 класс Pattern включает новый флаг UNICODE_CHARACTER_CLASS
, который делает предопределенные классы символов и POSIX классы символов соответствуют Unicode Technical Standard # 18: Unicode Regular Expression. Когда флаг активен, предопределенный класс символов и соответствующий класс символов POSIX станут эквивалентными (соответствуют одному и тому же).
Список символов совпадает с .NET.
Этого достаточно, чтобы сбить с ума!
\p{Space}
является более "стабильным" вариантом, поскольку он соответствует стандарту POSIX в режиме по умолчанию и Unicode Technical Standard # 18: Unicode Regular Expression в UNICODE_CHARACTER_CLASS
.
Если вы используете класс символов POSIX, реализация, совместимая с POSIX, будет иметь такое же поведение в режиме ASCII, а двигатели регулярных выражений Unicode, которые следуют рекомендациям, будут иметь (почти) одинаковое поведение в режиме Unicode.
\s
и \p{Space}
эквивалентны в Java, независимо от флага. Если вы используете \s
в Java, вы можете быть уверены, что следуете некоторым стандартам/рекомендациям. Просто, что это не объявляет большинству программистов об этом факте.
\p{isJavaWhitespace}
для сопоставления пробелов в соответствии с определение Java. Имя функции крайне вводит в заблуждение.
Ответ 3
Если у вас нет конкретной причины использовать другие параметры, я бы сохранил это просто и использовал \s