Начиная с функциональных интерфейсов Java 8, String#replaceAll()
принимает функцию преобразования для изменения согласованных подпоследовательностей "на лету" и построения окончательного результата.
Во-первых, предупреждение: регулярные выражения являются фантастическими, невероятно мощными инструментами для определенного класса проблем . Перед применением регулярных выражений вы должны определить, поддается ли проблема. Обычно обработка XML является противоположностью проблемы, поддающейся регулярному выражению, за исключением того случая, когда целью является обработка ввода как простой строки, а не как XML. (Однако внимательно прочитайте предостережение ниже)
Вот известная цитата Джейми Завински в 1997 году:
Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения». Теперь у них две проблемы.
Решение
С этими оговорками, вот код вашего вопроса:
String input="<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>";
Matcher m = Pattern.compile("-[a-zA-Z]").matcher(input);
// Do all the replacements in one statement using the functional replaceAll()
String result = m.replaceAll(s -> s.group().substring(1).toUpperCase());
Объяснение
Регулярному выражению соответствует один дефис, за которым следует любой алфавитный символ, прописные или строчные. replaceAll()
сканирует ввод, используя Matcher
. При каждом совпадении он вызывает лямбду (функциональное сокращение для анонимного класса с единственным методом apply()
), передающую аргумент String
, содержащий сопоставленный текст. Все, что возвращает лямбда, затем подставляется в выходную строку, которая строится методом replaceAll()
, вместо соответствующей строки.
Протест
Приведенное выше решение полностью закрывает структуру XML, оно изменит любую комбинацию -a
(где a
обозначает любую букву) и заменит ее просто A
(где A
обозначает прописная буква), независимо от того, где он появляется.
В приведенном вами примере этот шаблон встречается только в именах тегов. Однако, если существуют другие части файла, которые содержат (или могут содержать) этот шаблон, эти экземпляры также будут заменены. Это может быть проблемой, если этот шаблон встречается в текстовых данных (то есть вещи не внутри, но между тегами ) или в качестве значения атрибута. Этот метод применения регулярных выражений ко всему файлу вслепую является своего рода подходом бензопилы. Если вам действительно нужна бензопила, используйте ее.
Однако, если окажется, что бензопила слишком мощная, а ваша реальная задача требует более изощренной работы, вам потребуется переключиться на настоящий XML-парсер (JDK включает в себя хороший), который может обрабатывать все тонкости. Он предоставляет вам различные синтаксические фрагменты, такие как имя тега, имена атрибутов, значения атрибутов, текст и т. Д. По отдельности, так что вы можете явно решить, какие части должны быть затронуты. Вы все еще используете replaceAll()
выше, но применяете его только к тем частям, где это было необходимо.
Почти как правило, вы АБСОЛЮТНО НЕ будете использовать регулярные выражения для обработки XML, разбирать строки, содержащие вложенные или экранированные кавычки, или разбирать файлы CSV или TSV. Эти форматы данных обычно не подходят для использования регулярных выражений.