\ s фактически не захватывает все пробельные символы - PullRequest
3 голосов
/ 18 июня 2019

В моем приложении на Java 8 я сканирую пропущенные в тексте пробелы. Но \s в моем Регулярном выражении не захватывает все пробелы.Единственный пробел, который я обнаружил, что он не захватывает до сих пор в моем тестировании, это неразрывный пробел (Unicode 00A0).Это было мое регулярное выражение, которое сталкивалось с этой проблемой:

Pattern p = Pattern.compile("\\s");

Чтобы решить эту проблему, я добавил \h к своему регулярному выражению:

Pattern p = Pattern.compile("[\\s\\h]");

Теперь, есть ли другиепробелы, которые мне нужно знать, которые не будут захвачены \s\h?

Ответы [ 3 ]

5 голосов
/ 18 июня 2019

По умолчанию \s соответствует только пробельным символам ASCII ([ \t\n\x0B\f\r]).Есть два способа преодолеть это ограничение

  1. Использовать свойства символов Unicode: Pattern.compile("\\p{IsWhiteSpace}")

  2. Заставить предопределенный класс символов использовать свойства Unicode:
    Pattern.compile("\\s", Pattern.UNICODE_CHARACTER_CLASS)
    Это также можно включить с помощью встроенного флага (?U)

Pattern[] pattern = {
    Pattern.compile("\\s"),
    Pattern.compile("\\s", Pattern.UNICODE_CHARACTER_CLASS),
    Pattern.compile("((?U)\\s)"),
    Pattern.compile("\\p{IsWhiteSpace}")
};
String s = " \t\n\u00A0\u2002\u2003\u2006\u202F";
for(Pattern p: pattern) {
    int count = 0;
    for(Matcher m = p.matcher(s); m.find(); ) count++;
    System.out.printf("%-19s: %d matches%n",
      p.pattern()+((p.flags()&Pattern.UNICODE_CHARACTER_CLASS)!=0? " [(?U) via flags]": ""),
      count);
}
\s                 : 3 matches
\s [(?U) via flags]: 8 matches
((?U)\s)           : 8 matches
\p{IsWhiteSpace}   : 8 matches
3 голосов
/ 18 июня 2019

Согласно документации класса Pattern символы, соответствующие \s, равны \t\n\x0B\f\r.

Однако Unicode действительно поддерживает гораздо больше пробелов ,Примеры включают:

  • \u2002: пробел
  • \u2003: пробел
  • \u2003: пробел
  • \u202F: Узкое пространство без перерывов
1 голос
/ 18 июня 2019

Мы используем guava для этого ...

String s = " \t\n\u00A0\u2002\u2003\u2006\u202F";
int b = CharMatcher.whitespace().countIn(s);
System.out.println(b); // 8
...