Вопрос по java, regex, string – Regex для преобразования CamelCase в camel_case в Java

64

Я понимаю, почему желаемый вывод не дается для преобразования с помощью регулярного выражения строки, какFooBar вFoo_Bar который вместо этого даетFoo_Bar_, Я мог бы сделать что-то с String.substringsubstring(0, string.length() - 2) или просто заменили последнего персонажа, но я думаю, что есть лучшее решение для такого сценария.

Вот код:

<code>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
*/
</code>

Вопрос: Ищете более аккуратный способ получить желаемый результат?

Этот вопрос похож наstackoverflow.com/questions/4886091/… Paul Vargas

Ваш Ответ

9   ответов
128

вопрос а такжеCaseFormat from guava

в вашем случае что-то вроде:

CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "SomeInput");
Ссылка CaseFormat не в сети. Замена естьhere
@Anticom, отредактировано; Спасибо :)
@eliocs вопрос не был помечен как android и "аккуратнее". Все равно спасибо за отрицание;)
0

чтобы преобразовать некоторые ключи в формате верблюжьих букв в нижний регистр с подчеркиванием. Регулярное выражение, которое я придумал:

(?<!^|_|[A-Z])([A-Z])

В английском это означаетcapital letter which is not preceded by the start of the string, an underscore or another capital letter.

В приведенных ниже примерах жирным шрифтом обозначены те символы, которые должны соответствовать, используя вышеупомянутое регулярное выражение:

CamelCaseToSomethingElse camelCaseToSomethingElse camel_case_to_something_else Camel_Case_To_Something_Else CAMEL_CASE_TO_SOMETHING_ELSE

Обратите внимание, что выражение не влияет на строку, которая уже в нижнем регистре + символ подчеркивания.

Шаблон замены будет:

_l$1

Что значитlower case of first capturing groupпервая группа захвата - заглавная буква. Впоследствии вы также можете записать всю строку в нижнем регистре, чтобы нормализовать последние два образца из списка выше.

54

все будет в порядке

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());
    }
}
Примечание. Если во входной строке разрешены однобуквенные слова, например, & lt; thisIsATest & quot ;, приведенный выше код напечатает & lt; this_is_atest & quot ;. Гуава в принятом ответе приводит к & quot; this_is_a_test & quot ;.
2

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

Прочитайте документацию для(?=X) и т.п.

Лично я бы на самом делеsplit строка, а затем рекомбинируйте ее. Это может быть даже быстрее, если все сделано правильно, и это делает код намного проще для понимания, чем магия регулярного выражения. Не поймите меня неправильно: я люблю регулярные выражения. Но это не совсем аккуратное регулярное выражение, и при этомtransformation классическая задача регулярного выражения. Ведь кажется, ты тоже хочешь делать строчными?

Уродливый, но быстрый взлом будет заменить(.)([A-Z]+) с$1_$2 и затем строчные буквы всей строки впоследствии (если вы не можете сделать расширенные регулярные выражения в стиле Perl, где вы можете напрямую заменить строчные буквы!). Тем не менее, я рассматриваю расщепление при переходе от нижнего к верхнему, затем к преобразованию, а затем к объединению, как правильный и наиболее читаемый способ сделать это.

Да, в конце концов я бы тоже хотел, чтобы он был в нижнем регистре ajmartin
Так что я бы разбил его на куски, соответствующие[A-Z][a-z]*строчными буквами первая буква, и присоединиться к ним. Или трюк с заменой + строчными буквами, который я только что добавил к основному ответу.
4

$?

String text = "CamelCaseToSomethingElse";
System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "$1_$2"));

Обратите внимание, что эта версия безопасна для исполнения на чем-то, что уже покрыто верблюдом.

Вы пытаетесь использовать^ а также$ как якоря? Потому что их значения меняются, когда вы помещаете их в класс персонажа.[^$_A-Z] соответствует любому символу, который не является$, _или заглавная буква, и я не думаю, что это то, что вы имели в виду.
Не собираюсь как якорь, пытаюсь не соответствовать верхнему символу$ был ошибочно добавлен как метод, который я использую для имен классов.
1
([A-Z][a-z\d]+)(?=([A-Z][a-z\d]+))

за которой следуют строчные буквы. Позитивный прогноз будет искать другое слово, начинающееся с заглавной буквы, за которой следуют строчные буквы, но НЕ включит его в соответствие.

Смотри сюда:http://regexr.com?30ooo

2

это было бы безумно сложно в любом случае.

Попробуйте эту функцию с автоматическим распознаванием сокращений.

Unfortunately Guava lib doesn't auto detect upper case acronyms, so "bigCAT" would be converted to "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();
}
1
public class ReplaceFromCameltoSnake {
    public static void main(String args[]){
        String s1=" totalAmountWithoutDiscount";  
        String replaceString=s1.replaceAll("([A-Z]+)","\\_$1").toLowerCase(); 
        System.out.println(replaceString);  
    }
}
$ 1 - используется для создания группы
Не просто отправьте код, добавьте объяснение.
32

String replaceAll = key.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
Что если моя строка содержит число - mode3 заканчивается как mode3, тогда как я хотел бы mode_3.
Пятно AF. Красиво сделано!

Похожие вопросы