Отказ
Поскольку в нескольких ответах уже говорилось о большей эффективности сборщиков строк и т. Д., Я хотел показать вам, как это можно сделать с помощью регулярных выражений, и рассмотреть преимущества использования этого подхода.
Одно решение REGEX
Использование этого подходящего регулярного выражения (аналогично выражению Алана Мура ):
(.{3})(.{3})(.{4})
позволяет точно сопоставить 10 символов в 3 группах, а затем использовать выражение замены, которое ссылается на эти группы, с добавлением дополнительных символов:
($1) $2-$3
производя замену, как вы просили. Конечно, он также будет соответствовать знакам препинания и буквам, что является причиной для использования \d
(кодируется в строку Java как \\d
), а не .
подстановочный знак.
Почему РЕГЭКС?
Потенциальным преимуществом подхода регулярных выражений к чему-то подобному является сжатие «логики» для манипулирования строками. Поскольку вся «логика» может быть сжата в строку символов, а не в предварительно скомпилированный код, строки сопоставления и замены регулярных выражений могут быть сохранены в базе данных для облегчения манипулирования, обновления или настройки опытным пользователем системы. Это усложняет ситуацию на нескольких уровнях, но дает значительно большую гибкость для пользователей.
При других подходах (манипулирование строками) изменение алгоритма форматирования таким образом, чтобы он выдавал (555)123-4567
или 555.123.4567
вместо указанного вами (555) 123-4567
, по сути, было бы невозможно просто через пользовательский интерфейс. с подходом регулярных выражений изменение будет таким же простым, как изменение ($1) $2-$3
(в базе данных или аналогичном хранилище) на $1.$2.$3
или ($1)$2-$3
, в зависимости от ситуации.
Если вы хотите изменить свою систему так, чтобы она принимала «более грязные» данные, которые могут включать различные попытки форматирования, такие как 555-123.4567
, и переформатировать их во что-то непротиворечивое, можно было бы создать алгоритм манипуляции со строками, который бы быть способным на это и перекомпилировать приложение, чтобы работать так, как вам хотелось бы. Однако с помощью регулярных выражений пересмотр системы не потребовался бы - просто измените выражения синтаксического анализа и замены, например, так (может быть, это немного сложно для начинающих понять сразу):
^\D*1?\D*([2-9])\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d).*$
($1$2$3) $4$5$6-$7$8$9$10
Это позволит значительно улучшить возможности программы, как показано в следующем переформатировании:
"Input" "Output"
----------------------------- --------------------------------
"1323-456-7890 540" "(323) 456-7890"
"8648217634" "(864) 821-7634"
"453453453322" "(453) 453-4533"
"@404-327-4532" "(404) 327-4532"
"172830923423456" "(728) 309-2342"
"jh345gjk26k65g3245" "(345) 266-5324"
"jh3g24235h2g3j5h3" "(324) 235-2353"
"12345678925x14" "(234) 567-8925"
"+1 (322)485-9321" "(322) 485-9321"
"804.555.1234" "(804) 555-1234"
"08648217634" <no match or reformatting>
Как видите, он очень «терпим» к «форматированию» ввода и знает, что 1
следует игнорировать в начале числа и что 0
должно вызывать ошибку, поскольку оно недопустимо - все сохранено в одну строку.
Вопрос сводится к производительности и возможности настройки. Манипуляции со строками выполняются быстрее, чем регулярные выражения, но будущая настройка улучшений требует перекомпиляции, а не простого изменения строки. Тем не менее, есть вещи, которые не могут быть выражены очень хорошо (или даже в такой удобочитаемой форме, как описанные выше изменения), и некоторые вещи, которые невозможно сделать с помощью регулярных выражений.
TL; DR:
Regex позволяет хранить алгоритмы синтаксического анализа в сравнительно короткой строке, которую можно легко сохранить, чтобы можно было изменять без перекомпиляции. Простые, более сфокусированные функции манипуляции со строками более эффективны и иногда могут выполнять больше, чем регулярное выражение. Ключ должен понимать как инструменты, так и требования приложения и использовать тот, который наиболее подходит для ситуации.