#java #regex
#java #регулярное выражение
Вопрос:
Я пытаюсь перевести строку и поставить символ подчеркивания перед любым символом верхнего регистра. Самое близкое, что у меня есть, это:
out=in.replaceAll("([^_])([A-Z])","$1_$2");
но с "ABCDEF"
он возвращает "A_BC_DE_F"
, я думаю, потому что после рассмотрения «AB» он не смотрит на «BC», потому что «B» уже было в предыдущем совпадении. Конечно, я мог бы применить это дважды, но есть ли более элегантное решение?
Существует также:
out=in.replaceAll("([A-Z])","_$1");
но это добавляет начало "_"
.
Java 1.8, если это имеет значение
Комментарии:
1. Попробуйте
replaceAll("(?<!_)([A-Z])","_$1");
2. Чтобы избежать начала,
_
используйтеreplaceAll("(?<!_|^)([A-Z])","_$1");
илиreplaceAll("(?<!_)(?<=.)([A-Z])","_$1");
3. Вы можете использовать
.replaceAll("(?<=[^_])[A-Z]","_$0");
, просто поместите отрицаемый символьный класс в положительный вид сзади. Нет необходимости заключать весь шаблон использования в захватывающие круглые скобки,$0
обратные ссылки означают полное значение соответствия. Посмотрите эту демонстрацию Java .
Ответ №1:
Вы можете поместить [^_]
класс отрицаемых символов в непотребляющий положительный вид сзади
s = s.replaceAll("(?<=[^_])[A-Z]","_$0");
Обратите внимание, что нет необходимости заключать весь шаблон использования в захватывающие круглые скобки, $0
обратная ссылка обозначает полное значение соответствия.
Смотрите эту демонстрацию Java:
System.out.println(
"ABCDEF".replaceAll("(?<=[^_])[A-Z]","_$0")
); // => A_B_C_D_E_F
Ответ №2:
Зачем использовать regex??
String underscoreUppercase(String target){
StringBuilder b=new StringBuilder();
boolean first=true;
for(char c:target.toCharArray()){
if(Character.isUpperCase(c) amp;amp; !first){//to ommit leading underscore
b.append('_');
}
first=false;
b.append(c);
}
return b.toString();
}
для ABCDE
этого будет A_B_C_D_E
Комментарии:
1. Неожиданно? Чего тогда ожидать? Я пытаюсь перевести строку и поставить символ подчеркивания перед любым символом верхнего регистра
Ответ №3:
Здесь вы можете использовать позитивный прогноз
Регулярное выражение:, ([A-Z])(?=([A-Z]))
где (?=([A-Z]))
— не требующий использования положительный прогноз
public static void main(String[] args) {
String in = "ABCDEF";
String out = in.replaceAll("([A-Z])(?=([A-Z]))", "$1_");
System.out.println(out);
}
Ответ №4:
В качестве альтернативы вы можете разделить строку на каждый символ верхнего регистра и объединить обратно, используя подчеркивание
String in = "ABCDEF";
String out = String.join("_", in.split("(?=\p{Upper})"));
System.out.println(out);
Комментарии:
1. Да, тоже хорошее решение. Я предполагал что-то подобное, но не смог заставить это работать.