Вопрос по unicode, java – Почему неразрывный пробел не является пробельным символом в Java?

29

При поиске подходящего способа обрезать неразрывный пробел из проанализированного HTML, я впервые наткнулся на спартанское определение java:String.trim() что по крайней мере правильно задокументировано. Я хотел избежать явного перечисления символов, подходящих для обрезки, поэтому я предположил, что использование методов с поддержкой Unicode в классе Character сделает эту работу за меня.

Это когда я обнаружил, чтоCharacter.isWhitespace (символ) явно исключает неразрывные пробелы:

It is a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space ('\u00A0', '\u2007', '\u202F').

Это почему?

Реализациясоответствующий эквивалент .NET менее разборчив.

Ваш Ответ

7   ответов
7

что реализация Java более правильна, чем .NET. Неразрывный пробел по сути является непробельным символом, который выглядит как один. То есть, если у вас есть строки & quot; foo & quot; и & quot; bar & quot; и помещая между ними любой традиционный символ пробела, вы получите разрыв слова. Однако неразрывный пробел не разделяет их.

Неразрывный пробел все еще является границей слова. «Взлом» в "неразрывном пробеле" относится к тому, как это должно быть истолковано в целяхlineломать, а не разрывать слова.
2

isWhitespace) несовместимо с его функцией (для обнаружения разделителей). «Разделитель» функциональность довольно ясна, если вы посмотрите на полный список символов со страницы Javadoc, которую вы цитировали:

* It is a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space ('\u00A0', '\u2007', '\u202F').
* It is '\u0009', HORIZONTAL TABULATION.
* It is '\u000A', LINE FEED.
* It is '\u000B', VERTICAL TABULATION.
* It is '\u000C', FORM FEED.
* It is '\u000D', CARRIAGE RETURN.
* It is '\u001C', FILE SEPARATOR.
* It is '\u001D', GROUP SEPARATOR.
* It is '\u001E', RECORD SEPARATOR.
* It is '\u001F', UNIT SEPARATOR. 

Предполагается, что функция неразрывного пробела является визуальным пространством между словами, которое не разделено алгоритмами переноса слов.

2

StringUtils.isBlank () (и связанные функции), который имеет то же самое странноеisWhitespace поведение, то есть неразрывный пробел считается непустым.

14

isSpaceChar(int) метод. Разве это не делает то, что вы хотите?

Determines if the specified character (Unicode code point) is a Unicode space character. A character is considered to be a space character if and only if it is specified to be a space character by the Unicode standard. This method returns true if the character's general category type is any of the following: ...

Error: User Rate Limit Exceededtrimфункция, котораяusesError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededisSpaceChar(char)Error: User Rate Limit Exceeded
12

Как написано выше,isSpaceChar(int) предоставит ОП трек к ответу. Это выглядит довольно незаметно, но этот метод на самом делеможно использовать с регулярными выражениями. So:

    "X\u00A0X X".replaceAll("\\p{javaSpaceChar}", "_");

будет производить "X_X_X"; строка. В качестве упражнения для читателя предложено найти регулярное выражение для обрезки строки. (Шаблон с некоторыми флагами должен помочь.)

Error: User Rate Limit Exceededdocs.oracle.com/javase/7/docs/api/java/util/regex/…Error: User Rate Limit Exceededdocs.oracle.com/javase/7/docs/api/java/lang/…
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
6

когда неразрывный пробел следует обрабатывать особым образом, - это код, предназначенный для переноса текста в слова.

Для всех других целей, включая подсчет слов, усечение и общее разбиение по границам слов, неразрывный пробелis still whitespace.

Любой аргумент, что неразрывный пробел просто выглядит как & quot; пробел, но не конфликтующий со всей точкой Unicode, которая представляет символы на основе их значения, а не того, как они отображаются.

Таким образом, IMHO, реализация Java String.trim () не работает должным образом, и основная функция Character.isWhitespace () ошибается.

Я предполагаю, что разработчики Java написали isWhitespace (), основываясь на необходимости выполнения переноса текста в элементах управления. Они должны были назвать эту функцию isWordWrappingBoundary () или что-то более понятное, и использовать менее строгий тест для пробела для trim ().

Error: User Rate Limit Exceeded
21

Character.isWhitespace(char) Старый. Действительно старый. Многие вещи, сделанные в первые дни Java, следовали соглашениям и реализациям C.

Теперь, более десяти лет спустя, эти вещи кажутся ошибочными. Считайте это свидетельством того, как далеко продвинулись дела, даже между первыми днями Java и первыми днями .NET.

Java стремится быть на 100% обратно совместимым. Поэтому, даже если команда Java подумала, что было бы неплохо исправить свою первоначальную ошибку и добавить неразрывные пробелы в набор символов, который возвращает true из Character.isWhitespace (char), они не могут этого сделать, поскольку почти наверняка существует программное обеспечение, которое полагается на текущую реализацию, работающую точно так же, как и раньше.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы