Первое слово из PascalCase в нижнем регистре

У меня есть строка, которая содержит текст в PascalCase, и мне нужно извлечь из него первое слово и преобразовать его в нижний регистр:

assert firstWord('PmdExtension') == 'pmd'
assert firstWord('PMDExtension') == 'p'
assert firstWord('Pmd') == 'pmd'
assert firstWord('CodeQualityExtension') == 'code'

static String firstWord(String word) {
    return '???'
}

Давайте сосредоточимся только на допустимых идентификаторах PascalCase (без каких-либо других символов, цифр и всегда начиная с заглавной буквы).

Каково было бы простое и чистое решение для моей проблемы?

я пробовал

word.split(/[A-Z]/).first().join(' ')

но он удаляет все заглавные буквы, а мне нужно их сохранить.

4 ответа

assert firstWord('PmdExtension') == 'pmd'
assert firstWord('PMDExtension') == 'p'
assert firstWord('Pmd') == 'pmd'
assert firstWord('CodeQualityExtension') == 'code'
assert firstWord('') == ''
assert firstWord(null) == ''

static String firstWord(String word) {
    word ? word.split(/(?=\p{Lu})/)[0].toLowerCase() : ''

    // A verbose way would be as below (omitting the null check for brevity)
    // word[0].toLowerCase() + word[1..-1].takeWhile { Character.isLowerCase(it) }
}

Groovy найти оператор (=~), кажется, делает работу хорошо:

static String firstWord(String word) {
    word ? (word =~ /[A-Z][a-z]*/)[0].toLowerCase() : ''
}

Что-то вроде:

static String firstWord(String word) {
    return word[0].toLowerCase()+word.split(['A'..'Z'].join('|'))[1]
}

inject Метод можно использовать для накопления символов, пока не встретится вторая заглавная буква:

def firstWord(String word) {
    def numCapsObserved = 0
    def initVal = ""

    word.inject(initVal, { val, letter -> 
        def result = val
        if (letter ==~ /[A-Z]/) { numCapsObserved++ } 

        if (numCapsObserved < 2) {
            result += letter.toLowerCase() 
        }
        return result
    }) 
}

assert firstWord('PmdExtension') == 'pmd'
assert firstWord('PMDExtension') == 'p'
assert firstWord('Pmd') == 'pmd'
assert firstWord('CodeQualityExtension') == 'code'
Другие вопросы по тегам