Я понимаю , почему желаемый результат не дается для преобразования с использованием регулярных выражений в строку , как FooBar
в Foo_Bar
который вместо дает Foo_Bar_
. Я мог бы что-то сделать с String.substring substring(0, string.length() - 2)
или просто заменить последний символ, но я думаю, что есть лучшее решение для такого сценария.
Вот код:
String regex = "([A-Z][a-z]+)";
String replacement = "$1_";
"CamelCaseToSomethingElse".replaceAll(regex, replacement);
/*
outputs: Camel_Case_To_Something_Else_
desired output: Camel_Case_To_Something_Else
*/
Вопрос: Ищете более аккуратный способ получить желаемый результат?
Ответы:
См. Этот вопрос и
CaseFormat
от гуавыв вашем случае что-то вроде:
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "SomeInput");
источник
свяжите нижний и верхний регистры как две группы, все будет в порядке
public class Main { public static void main(String args[]) { String regex = "([a-z])([A-Z]+)"; String replacement = "$1_$2"; System.out.println("CamelCaseToSomethingElse" .replaceAll(regex, replacement) .toLowerCase()); } }
источник
IBMIsMyCompany
.Вы можете использовать нижеприведенный фрагмент кода:
String replaceAll = key.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
источник
MyUUID
Я понял, что это не преобразование верблюжьего регистра, как правильное подчеркиваниеmy_uu_id
.Я не могу предоставить RegEx, это все равно было бы безумно сложно.
Попробуйте эту функцию с автоматическим распознаванием акронимов.
К сожалению, Guava lib не определяет автоматически аббревиатуры в верхнем регистре, поэтому bigCAT будет преобразован в BIG_C_A_T.
/** * Convert to UPPER_UNDERSCORE format detecting upper case acronyms */ private String upperUnderscoreWithAcronyms(String name) { StringBuffer result = new StringBuffer(); boolean begin = true; boolean lastUppercase = false; for( int i=0; i < name.length(); i++ ) { char ch = name.charAt(i); if( Character.isUpperCase(ch) ) { // is start? if( begin ) { result.append(ch); } else { if( lastUppercase ) { // test if end of acronym if( i+1<name.length() ) { char next = name.charAt(i+1); if( Character.isUpperCase(next) ) { // acronym continues result.append(ch); } else { // end of acronym result.append('_').append(ch); } } else { // acronym continues result.append(ch); } } else { // last was lowercase, insert _ result.append('_').append(ch); } } lastUppercase=true; } else { result.append(Character.toUpperCase(ch)); lastUppercase=false; } begin=false; } return result.toString(); }
источник
Почему бы просто не сопоставить предыдущий символ как начало строки
$
?String text = "CamelCaseToSomethingElse"; System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "$1_$2"));
Обратите внимание, что эта версия безопасна для выполнения на чем-то, что уже заделано верблюжьей оболочкой.
источник
^
и в$
качестве якорей? Потому что их значения меняются, когда вы помещаете их в класс персонажей.[^$_A-Z]
соответствует любому символу, который не$
,_
или прописной буквы, и я не думаю , что это то , что вы имели в виду.$
был ошибочно добавлен, поскольку это метод, который я использую для имен классов.Добавьте утверждение опережающего просмотра нулевой ширины.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Прочтите документацию
(?=X)
и т. Д.Лично я бы разделил строку, а затем рекомбинировал ее. Это может быть даже быстрее, если все сделано правильно, и это делает код намного проще для понимания, чем магия регулярных выражений. Не поймите меня неправильно: я люблю регулярные выражения. Но на самом деле это не изящное регулярное выражение, и это преобразование не является классической задачей регулярного выражения. В конце концов, кажется, вы тоже хотите писать строчные буквы?
Некрасивый , но быстрый хак бы заменить
(.)([A-Z]+)
с ,$1_$2
а затем в нижнем регистре всей строки после этого (если вы не можете сделать Perl-стиль extrended регэксп, где вы можете нижние регистр замены сразу!). Тем не менее, я считаю разделение при переходе снизу вверх, затем преобразование, а затем соединение как правильный и наиболее читаемый способ сделать это.источник
[A-Z][a-z]*
первой букве в нижнем регистре, и воссоединил их. Или трюк с заменой и строчными буквами, который я только что добавил к основному ответу.public class ReplaceFromCameltoSnake { public static void main(String args[]){ String s1=" totalAmountWithoutDiscount"; String replaceString=s1.replaceAll("([A-Z]+)","\\_$1").toLowerCase(); System.out.println(replaceString); } }
источник
Не уверен, что с чистым регулярным выражением возможно что-то действительно сплошное. Особенно для поддержки аббревиатур.
Я сделал небольшую функцию, вдохновленную ответом @radzimir, которая поддерживает акронимы и не содержит буквенных символов:
С https://gist.github.com/ebuildy/cf46a09b1ac43eea17c7621b7617ebcd :
private static String snakeCaseFormat(String name) { final StringBuilder result = new StringBuilder(); boolean lastUppercase = false; for (int i = 0; i < name.length(); i++) { char ch = name.charAt(i); char lastEntry = i == 0 ? 'X' : result.charAt(result.length() - 1); if (ch == ' ' || ch == '_' || ch == '-' || ch == '.') { lastUppercase = false; if (lastEntry == '_') { continue; } else { ch = '_'; } } else if (Character.isUpperCase(ch)) { ch = Character.toLowerCase(ch); // is start? if (i > 0) { if (lastUppercase) { // test if end of acronym if (i + 1 < name.length()) { char next = name.charAt(i + 1); if (!Character.isUpperCase(next) && Character.isAlphabetic(next)) { // end of acronym if (lastEntry != '_') { result.append('_'); } } } } else { // last was lowercase, insert _ if (lastEntry != '_') { result.append('_'); } } } lastUppercase = true; } else { lastUppercase = false; } result.append(ch); } return result.toString(); }
источник
Следует искать заглавную букву, за которой следуют строчные буквы. Положительный просмотр вперед будет искать другое слово, начинающееся с заглавной буквы, за которой следуют строчные буквы, но НЕ будет включать его в соответствие.
Смотрите здесь: http://regexr.com?30ooo
источник
Мне пришлось реализовать это, чтобы преобразовать некоторые ключи в формате верблюжьего регистра в нижний регистр с подчеркиванием. Я придумал регулярное выражение:
(?<!^|_|[A-Z])([A-Z])
На английском это означает заглавную букву, которой не предшествует начало строки, подчеркивание или другая заглавная буква .
В приведенных ниже примерах жирным шрифтом выделены символы, которые должны обеспечивать соответствие с использованием вышеупомянутого регулярного выражения:
Обратите внимание, что выражение не влияет на строку, которая уже находится в формате нижнего регистра + подчеркивание.
Шаблон замены будет таким:
_l$1
Это означает нижний регистр первой группы захвата , первая группа захвата - заглавная буква. Впоследствии вы можете строчить всю строку, чтобы нормализовать последние два образца из списка выше.
источник