В Котлине, если мы используем:
string.split(Regex("\\s+"))
Затем мы можем разбить строку на слова, разделенные пробелом. Однако строка:
val string = "a\u2000b"
не разделяется, так как регулярное выражение не соответствует символам пробела Юникода.
Есть ли способ разделить строку на все пробельные символы?
Я использовал следующее регулярное выражение для соответствия пробелам Unicode:
Regex("[\\p{javaWhitespace}\u00A0\u2007\u202F]+")
Это работает, потому что, хотя \s
соответствует только пробелам Latin-1, \p{javaWhitespace}
соответствует всему, для чего Character.isWhitespace()
верно. По какой-то причине это не включает несколько конкретных персонажей, которые я перечислил отдельно.
Дополнительная информация в документах для Шаблон.
Связанный с этим факт: хотя java.lang.String.trim() не удаляет неразрывные пробелы или пробелы цифр, котлин.String.trim() удаляет!
Подождите секунду, на самом деле это неверно, поскольку «\ u2000» на самом деле интерпретируется как «\ u2000» + «b», что является символом пробела «EN QUAD», за которым следует буква «b». Я вернул вопрос в его первоначальную форму, поскольку это то, что я намеревался.
Ах да, в Java/Kotlin вам, вероятно, потребуется представить U+2000B как суррогатную пару… В любом случае, я уже отредактировал свой ответ, чтобы удалить эту неуместность, так что теперь мы просто запутываем всех остальных :-)
Поскольку Java 7 Pattern
позволяет указать флаг UNICODE_CHARACTER_CLASS
, который в основном также будет работать для вашей текущей проблемы:
Pattern.compile("\\s+", Pattern.UNICODE_CHARACTER_CLASS)
К сожалению, это пока не поддерживается напрямую через RegexOption
с Kotlins Regex
. Есть известная проблема, в которой также описывается обходной путь (KT-21094):
string.split("""(?U)\s+""".toRegex())
Вам (скорее всего) требуется Java 7+, чтобы это действительно работало. Альтернативой может быть использование других предопределенных классов символов. Однако вам нужно найти соответствующий Pattern
-javadoc для вашей версии Java, чтобы убедиться, что она действительно работает (или сделать это методом проб и ошибок ;-)).
Вы можете взглянуть на icu4j (site.icu-project.org/home/why-use-icu4j), в частности:
BreakIterator.getCharacterInstance()