Le titre dit à peu près tout. Quelle est la manière la plus simple/élégante de convertir, en Java, une chaîne du format "THIS_IS_AN_EXAMPLE_STRING"
au format "ThisIsAnExampleString
"? Je suppose qu'il doit y avoir au moins une façon de le faire en utilisant String.replaceAll()
et une expression régulière.
Mes pensées initiales sont les suivantes: faites précéder la chaîne d’un trait de soulignement (_
), convertissez-la en minuscule, puis utilisez replaceAll pour convertir chaque caractère précédé d’un trait de soulignement avec sa version majuscule.
Une autre option consiste à utiliser le com.google.common.base.CaseFormat
de Google Guava.
George Hawkins a laissé un commentaire avec cet exemple d'utilisation:
CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, "THIS_IS_AN_EXAMPLE_STRING");
Jetez un coup d’œil à WordUtils dans Apache Commons lang library:
Plus précisément, la méthode capitalizeFully (String str, délimiteurs de caractères []] devrait faire l'affaire:
String blah = "LORD_OF_THE_RINGS";
assertEquals("LordOfTheRings", WordUtils.capitalizeFully(blah, new char[]{'_'}).replaceAll("_", ""));
Barre verte!
static String toCamelCase(String s){
String[] parts = s.split("_");
String camelCaseString = "";
for (String part : parts){
camelCaseString = camelCaseString + toProperCase(part);
}
return camelCaseString;
}
static String toProperCase(String s) {
return s.substring(0, 1).toUpperCase() +
s.substring(1).toLowerCase();
}
Note : Vous devez ajouter une validation d'argument.
Avec Apache Commons Lang3 lib, c'est très simple.
import org.Apache.commons.lang3.StringUtils;
import org.Apache.commons.lang3.text.WordUtils;
public String getName(String text) {
return StringUtils.remove(WordUtils.capitalizeFully(text, '_'), "_");
}
Exemple:
getName("SOME_CONSTANT");
Donne:
"SomeConstant"
public static void main(String[] args) {
String start = "THIS_IS_A_TEST";
StringBuffer sb = new StringBuffer();
for (String s : start.split("_")) {
sb.append(Character.toUpperCase(s.charAt(0)));
if (s.length() > 1) {
sb.append(s.substring(1, s.length()).toLowerCase());
}
}
System.out.println(sb);
}
Voici un extrait de code qui pourrait aider:
String input = "ABC_DEF";
StringBuilder sb = new StringBuilder();
for( String oneString : input.split("_") )
{
sb.append( oneString.substring(0,1) );
sb.append( oneString.substring(1).toLowerCase() );
}
// sb now holds your desired String
Exemple Java 1.8 utilisant des flux
String text = "THIS_IS_SOME_TEXT";
String bactrianCamel = Stream.of(text.split("[^a-zA-Z0-9]"))
.map(v -> v.substring(0, 1).toUpperCase() + v.substring(1).toLowerCase())
.collect(Collectors.joining());
String dromedaryCamel = bactrianCamel.toLowerCase().substring(0, 1) + bactrianCamel.substring(1);
System.out.printf("%s is now %s%n", text, dromedaryCamel);
THIS_IS_SOME_TEXT est maintenant thisIsSomeText
public String withChars(String inputa) {
String input = inputa.toLowerCase();
StringBuilder sb = new StringBuilder();
final char delim = '_';
char value;
boolean capitalize = false;
for (int i=0; i<input.length(); ++i) {
value = input.charAt(i);
if (value == delim) {
capitalize = true;
}
else if (capitalize) {
sb.append(Character.toUpperCase(value));
capitalize = false;
}
else {
sb.append(value);
}
}
return sb.toString();
}
public String withRegex(String inputa) {
String input = inputa.toLowerCase();
String[] parts = input.split("_");
StringBuilder sb = new StringBuilder();
sb.append(parts[0]);
for (int i=1; i<parts.length; ++i) {
sb.append(parts[i].substring(0,1).toUpperCase());
sb.append(parts[i].substring(1));
}
return sb.toString();
}
Temps: en millisecondes.
Iterations = 1000
WithChars: start = 1379685214671 end = 1379685214683 diff = 12
WithRegex: start = 1379685214683 end = 1379685214712 diff = 29
Iterations = 1000
WithChars: start = 1379685217033 end = 1379685217045 diff = 12
WithRegex: start = 1379685217045 end = 1379685217077 diff = 32
Iterations = 1000
WithChars: start = 1379685218643 end = 1379685218654 diff = 11
WithRegex: start = 1379685218655 end = 1379685218684 diff = 29
Iterations = 1000000
WithChars: start = 1379685232767 end = 1379685232968 diff = 201
WithRegex: start = 1379685232968 end = 1379685233649 diff = 681
Iterations = 1000000
WithChars: start = 1379685237220 end = 1379685237419 diff = 199
WithRegex: start = 1379685237419 end = 1379685238088 diff = 669
Iterations = 1000000
WithChars: start = 1379685239690 end = 1379685239889 diff = 199
WithRegex: start = 1379685239890 end = 1379685240585 diff = 695
Iterations = 1000000000
WithChars: start = 1379685267523 end = 1379685397604 diff = 130081
WithRegex: start = 1379685397605 end = 1379685850582 diff = 452977
Pas sûr, mais je pense que je peux utiliser moins de mémoire et obtenir des performances fiables en procédant caractère par caractère. Je faisais quelque chose de similaire, mais dans les boucles dans les fils de fond, donc j'essaye cela pour le moment. J'ai une certaine expérience avec String.split étant plus cher que prévu. Et je travaille sur Android et je m'attends à ce que le hoquet du GC soit plus un problème que l'utilisation du processeur.
public static String toCamelCase(String value) {
StringBuilder sb = new StringBuilder();
final char delimChar = '_';
boolean lower = false;
for (int charInd = 0; charInd < value.length(); ++charInd) {
final char valueChar = value.charAt(charInd);
if (valueChar == delimChar) {
lower = false;
} else if (lower) {
sb.append(Character.toLowerCase(valueChar));
} else {
sb.append(Character.toUpperCase(valueChar));
lower = true;
}
}
return sb.toString();
}
Un indice que String.split est coûteux est que son entrée est une expression rationnelle (et non un caractère tel que String.indexOf) et renvoie un tableau (au lieu d'un itérateur, car la boucle n'utilise qu'une chose à la fois). Des cas tels que "AB_AB_AB_AB_AB_AB ..." brisent l'efficacité de la copie en bloc. Pour les chaînes longues, utilisez un ordre de grandeur supérieur à la mémoire, puis à la chaîne d'entrée.
Considérant que la boucle à travers les caractères n'a pas de cas canonique. Donc, pour moi, les frais généraux liés à une regex inutile et à un tableau semblent généralement moins préférables (puis renoncer à une efficacité de copie en bloc possible). Intéressé d'entendre des opinions/corrections, merci.
Vous pouvez utiliser org.modeshape.common.text.Inflector .
Plus précisément:
String camelCase(String lowerCaseAndUnderscoredWord, boolean uppercaseFirstLetter, char... delimiterChars)
Par défaut, cette méthode convertit les chaînes en UpperCamelCase.
L’artefact Maven est: org.modeshape: modeshape-common: 2.3.0.Final
sur le référentiel JBoss: https://repository.jboss.org/nexus/content/repositories/releases
Voici le fichier JAR: https://repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar
Vous pouvez aussi essayer ceci:
public static String convertToNameCase(String s)
{
if (s != null)
{
StringBuilder b = new StringBuilder();
String[] split = s.split(" ");
for (String srt : split)
{
if (srt.length() > 0)
{
b.append(srt.substring(0, 1).toUpperCase()).append(srt.substring(1).toLowerCase()).append(" ");
}
}
return b.toString().trim();
}
return s;
}
Il va convertir Enum Constant
en Camel Case. Ce serait utile pour quiconque cherche une telle fonctionnalité.
public enum TRANSLATE_LANGUAGES {
ARABIC("ar"), BULGARIAN("bg"), CATALAN("ca"), CHINESE_SIMPLIFIED("zh-CN"), CHINESE_TRADITIONAL("zh-TW"), CZECH("cs"), DANISH("da"), DUTCH("nl"), ENGLISH("en"), ESTONIAN("et"), FINNISH("fi"), FRENCH(
"fr"), GERMAN("de"), GREEK("el"), HAITIAN_CREOLE("ht"), HEBREW("he"), HINDI("hi"), HMONG_DAW("mww"), HUNGARIAN("hu"), INDONESIAN("id"), ITALIAN("it"), JAPANESE("ja"), KOREAN("ko"), LATVIAN(
"lv"), LITHUANIAN("lt"), MALAY("ms"), NORWEGIAN("no"), PERSIAN("fa"), POLISH("pl"), PORTUGUESE("pt"), ROMANIAN("ro"), RUSSIAN("ru"), SLOVAK("sk"), SLOVENIAN("sl"), SPANISH("es"), SWEDISH(
"sv"), THAI("th"), TURKISH("tr"), UKRAINIAN("uk"), Urdu("ur"), VIETNAMESE("vi");
private String code;
TRANSLATE_LANGUAGES(String language) {
this.code = language;
}
public String langCode() {
return this.code;
}
public String toCamelCase(TRANSLATE_LANGUAGES lang) {
String toString = lang.toString();
if (toString.contains("_")) {
String st = toUpperLowerCase(toString.split("_"));
}
return "";
}
private String toUpperLowerCase(String[] tempString) {
StringBuilder builder = new StringBuilder();
for (String temp : tempString) {
String char1 = temp.substring(0, 1);
String restString = temp.substring(1, temp.length()).toLowerCase();
builder.append(char1).append(restString).append(" ");
}
return builder.toString();
}
}
public String CamelCase(String str)
{
String CamelCase="";
String parts[] = str.split("_");
for(String part:parts)
{
String as=part.toLowerCase();
int a=as.length();
CamelCase = CamelCase + as.substring(0, 1).toUpperCase()+ as.substring(1,a);
}
return CamelCase;
}
C’est le programme le plus simple à convertir en CamelCase . Espérons que cela vous aidera.
protected String toCamelCase(String input) {
if (input == null) {
return null;
}
if (input.length() == 0) {
return "";
}
// lowercase the first character
String camelCaseStr = input.substring(0, 1).toLowerCase();
if (input.length() > 1) {
boolean isStartOfWord = false;
for (int i = 1; i < input.length(); i++) {
char currChar = input.charAt(i);
if (currChar == '_') {
// new Word. ignore underscore
isStartOfWord = true;
} else if (Character.isUpperCase(currChar)) {
// capital letter. if start of Word, keep it
if (isStartOfWord) {
camelCaseStr += currChar;
} else {
camelCaseStr += Character.toLowerCase(currChar);
}
isStartOfWord = false;
} else {
camelCaseStr += currChar;
isStartOfWord = false;
}
}
}
return camelCaseStr;
}
public static final String UPPER_CAMEL = "initUp";
public static final String LOWER_CAMEL = "initLow";
public String toCamel(String src, String separator, String format) {
StringBuilder builder = new StringBuilder(src.toLowerCase());
int len = builder.length();
for (int idx = builder.indexOf(separator); idx > 0 && idx < len; idx = builder.indexOf(separator, idx)) {
builder = builder.replace(idx, idx + 2, (String.valueOf(builder.charAt(idx + 1)).toUpperCase()));
}
switch (format) {
case LOWER_CAMEL:
builder.setCharAt(0, Character.toLowerCase(builder.charAt(0)));
break;
default:
builder.setCharAt(0, Character.toUpperCase(builder.charAt(0)));
break;
}
return builder.toString();
}
Invocation en tant que
toCamel("THIS_IS_AN_EXAMPLE_STRING", "_", UPPER_CAMEL)
Temps d'exécution: 14 ms
Une autre solution à cela peut être la suivante.
public static String toCamelCase(String str, String... separators) {
String separatorsRegex = "\\".concat(org.Apache.commons.lang3.StringUtils.join(separators, "|\\"));
List splits = Arrays.asList(str.toLowerCase().split(separatorsRegex));
String capitalizedString = (String)splits.stream().map(WordUtils::capitalize).reduce("", String::concat);
return capitalizedString.substring(0, 1).toLowerCase() + capitalizedString.substring(1);
}
Java 8 pour plusieurs chaînes:
import com.google.common.base.CaseFormat;
String camelStrings = "YOUR_UPPER, YOUR_TURN, ALT_TAB";
List<String> camelList = Arrays.asList(camelStrings.split(","));
camelList.stream().forEach(i -> System.out.println(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, i) + ", "));
Un simple snnipet:
public static String camelCase(String in) {
if (in == null || in.length() < 1) { return ""; } //validate in
String out = "";
for (String part : in.toLowerCase().split("_")) {
if (part.length() < 1) { //validate length
continue;
}
out += part.substring(0, 1).toUpperCase();
if (part.length() > 1) { //validate length
out += part.substring(1);
}
}
return out;
}
protected String toCamelCase(CaseFormat caseFormat, String... words){
if (words.length == 0){
throw new IllegalArgumentException("Word list is empty!");
}
String firstWord = words[0];
String [] restOfWords = Arrays.copyOfRange(words, 1, words.length);
StringBuffer buffer = new StringBuffer();
buffer.append(firstWord);
Arrays.asList(restOfWords).stream().forEach(w->buffer.append("_"+ w.toUpperCase()));
return CaseFormat.UPPER_UNDERSCORE.to(caseFormat, buffer.toString());
}