Как выбрать шаблон пробела?

В документации 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