Регулярное выражение для преобразования CamelCase в Camel case в java
Я понимаю, почему желаемый результат не дается для преобразования с помощью regex строку FooBar
to Foo_Bar
который вместо этого дает Foo_Bar_
. Я мог бы сделать что-нибудь со строкой.подстрока substring(0, string.length() - 2)
или просто заменить последний символ, но я думаю, что есть лучшее решение для такого сценария.
вот код:
String regex = "([A-Z][a-z]+)";
String replacement = "_";
"CamelCaseToSomethingElse".replaceAll(regex, replacement);
/*
outputs: Camel_Case_To_Something_Else_
desired output: Camel_Case_To_Something_Else
*/
вопрос: ищете более аккуратный способ получить желаемый результат?
9 ответов:
посмотреть этот вопрос и
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 = "_"; System.out.println("CamelCaseToSomethingElse" .replaceAll(regex, replacement) .toLowerCase()); } }
вы можете использовать ниже код:
String replaceAll = key.replaceAll("(.)(\p{Upper})", "_").toLowerCase();
почему бы просто не сопоставить предыдущий символ как не начало строки
$
?String text = "CamelCaseToSomethingElse"; System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "_"));
обратите внимание, что эта версия является безопасным для выполнения на то, что уже верблюд случае.
добавить утверждение нулевой ширины lookahead.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
читать документацию для
(?=X)
etc.лично я бы на самом деле сплит строка, а затем рекомбинировать его. Это может быть даже быстрее, когда все сделано правильно, и это делает код намного проще для понимания, чем магия регулярных выражений. Не поймите меня неправильно: я люблю регулярные выражения. Но это не действительно аккуратное регулярное выражение, и это трансформация классическая задача обработать. Ведь кажется вы тоже хотите делать строчные буквы?
уродливый, но быстрый хак будет заменить
(.)([A-Z]+)
С_
а затем в нижнем регистре всю строку после этого (если вы не можете сделать perl-стиль extrended regexps, где вы можете в нижнем регистре заменить непосредственно!). Тем не менее я рассматриваю расщепление при переходе от Нижнего к верхнему, затем преобразование, а затем присоединение как правильное и самое четкий способ сделать это.
([A-Z][a-z\d]+)(?=([A-Z][a-z\d]+))
следует искать заглавную букву, за которой следуют строчные буквы. Положительный lookahead будет искать другое слово, начинающееся с заглавной буквы, за которой следуют строчные буквы, но не будет включать его в матч.
смотрите сюда:http://regexr.com?30ooo
public class ReplaceFromCameltoSnake { public static void main(String args[]){ String s1=" totalAmountWithoutDiscount"; String replaceString=s1.replaceAll("([A-Z]+)","\_").toLowerCase(); System.out.println(replaceString); } }
Я не могу предоставить регулярное выражение, это было бы безумно сложно в любом случае.
попробуйте эту функцию с автоматическим распознаванием сокращений.
к сожалению, 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(); }
мне пришлось реализовать это, чтобы преобразовать некоторые ключи в формате camel case в нижний регистр с подчеркиванием. Регулярное выражение, которое я придумал:
(?<!^|_|[A-Z])([A-Z])
на английском языке это расшифровывается как заглавная буква, которой не предшествует начало строки, подчеркивание или другая заглавная буква.
в приведенных ниже примерах жирным шрифтом выделены символы, которые должны привести к совпадению с использованием вышеупомянутого регулярного выражение:
- верблюдCaseToS omethingElse
- верблюдCaseToS omethingElse
- camel_case_to_something_else
- Camel_Case_To_Something_Else
- CAMEL_CASE_TO_SOMETHING_ELSE
обратите внимание, что выражение не влияет на строку, которая уже находится в нижнем регистре + формат подчеркивания.
шаблон замены будут:
_l
что означает нижний регистр первой группы захвата, первая группа захвата является заглавной буквой. Вы могли бы в нижнем регистре всю строку после этого, а также нормализовать последние два образца из списка выше.