Как выбрать между пробелами?

В документации по шаблону Oracle есть описание трех различных шаблонов для сопоставления пробелов:

  1. \ s
  2. \ Р {пробел}
  3. \ Р {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

Другие вопросы по тегам