Rozumiem, dlaczego żądane dane wyjściowe nie są podawane do konwersji za pomocą wyrażenia regularnego na ciąg podobny FooBar
do Foo_Bar
który zamiast tego daje Foo_Bar_
. Mogłem coś zrobić z String.substring substring(0, string.length() - 2)
lub po prostu zamienić ostatni znak, ale myślę, że jest lepsze rozwiązanie takiego scenariusza.
Oto kod:
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
*/
Pytanie: Szukasz lepszego sposobu na uzyskanie pożądanego wyniku?
Odpowiedzi:
Zobacz to pytanie i
CaseFormat
od guawyw twoim przypadku coś takiego:
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "SomeInput");
źródło
połącz małe i duże litery jako dwie grupy, wszystko będzie dobrze
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()); } }
źródło
IBMIsMyCompany
. : .Możesz użyć poniższego fragmentu kodu:
String replaceAll = key.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
źródło
MyUUID
poprawnie podkreślał, mammy_uu_id
.Nie mogę podać RegEx, i tak byłoby to szalenie skomplikowane.
Wypróbuj tę funkcję z automatycznym rozpoznawaniem akronimów.
Niestety biblioteka Guava nie wykrywa automatycznie akronimów wielkich liter, więc „bigCAT” zostanie przekonwertowany na „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(); }
źródło
Dlaczego po prostu nie dopasować poprzedniego znaku jako nie początku wiersza
$
?String text = "CamelCaseToSomethingElse"; System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "$1_$2"));
Zauważ, że ta wersja jest bezpieczna do wykonania na czymś, co już jest okryte wielbłądem.
źródło
^
i$
jako kotwic? Ponieważ ich znaczenie zmienia się, gdy umieścisz je w klasie postaci.[^$_A-Z]
dopasowuje dowolny znak, który nie jest$
,_
lub wielkiej litery, a nie sądzę, że to, co masz na myśli.$
został omyłkowo dodany, ponieważ jest to technika, której używam do nazw klas.Dodaj asercję wyprzedzającą o zerowej szerokości.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Przeczytaj dokumentację
(?=X)
itp.Osobiście rozdzieliłbym strunę, a następnie ponownie ją połączył . Może to być nawet szybsze, jeśli zostanie wykonane poprawnie, i sprawia, że kod jest znacznie łatwiejszy do zrozumienia niż magia wyrażeń regularnych. Nie zrozum mnie źle: uwielbiam wyrażenia regularne. Ale to naprawdę nie jest zgrabne wyrażenie regularne, ani ta transformacja nie jest klasycznym zadaniem wyrażenia regularnego . W końcu wydaje się, że chcesz też pisać małymi literami?
Brzydka ale szybko siekać byłoby wymienić
(.)([A-Z]+)
z$1_$2
czym małe litery cały ciąg potem (o ile można to zrobić perl-styl extrended wyrażeń regularnych, w których można małe litery wymiany bezpośrednio!). Nadal uważam, że rozdzielenie przy przejściu z dołu do góry, następnie przekształcenie, a następnie połączenie się, jest właściwym i najbardziej czytelnym sposobem zrobienia tego.źródło
[A-Z][a-z]*
, małą pierwszą literą i ponownie połączyłem. Lub sztuczka zastępująca + małe litery, którą właśnie dodałem do głównej odpowiedzi.public class ReplaceFromCameltoSnake { public static void main(String args[]){ String s1=" totalAmountWithoutDiscount"; String replaceString=s1.replaceAll("([A-Z]+)","\\_$1").toLowerCase(); System.out.println(replaceString); } }
źródło
Nie jestem pewien, czy można mieć coś naprawdę samotnego przy użyciu czystego wyrażenia regularnego. Szczególnie do obsługi akronimów.
Zrobiłem małą funkcję, zainspirowaną odpowiedzią @radzimir, która obsługuje akronimy i nie ma znaków alfabetycznych:
Z 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(); }
źródło
Powinien szukać dużej litery, po której następują małe litery. Pozytywne spojrzenie w przód będzie szukać innego słowa zaczynającego się wielką literą, po której następują małe litery, ale NIE uwzględni go w dopasowaniu.
Zajrzyj tutaj: http://regexr.com?30ooo
źródło
Musiałem to zaimplementować, aby przekonwertować niektóre klucze w formacie wielbłąda na małe litery z podkreśleniami. Wyrażenie regularne, które wymyśliłem, to:
(?<!^|_|[A-Z])([A-Z])
W języku angielskim oznacza wielką literę, która nie jest poprzedzona początkiem ciągu, podkreśleniem lub inną dużą literą .
W poniższych przykładach pogrubione znaki to te, które powinny dać dopasowanie przy użyciu wyżej wymienionego wyrażenia regularnego:
Zwróć uwagę, że wyrażenie nie wpływa na ciągi już zapisane małymi literami + podkreślenie.
Wzorzec zastępczy wyglądałby tak:
_l$1
Oznacza to małe litery pierwszej grupy przechwytywania , przy czym pierwsza grupa przechwytywania jest wielką literą. Możesz później również małe litery w całym ciągu, aby znormalizować ostatnie dwie próbki z powyższej listy.
źródło