简体   繁体   中英

First word from PascalCase as lowercase

I have a string that contains text in PascalCase and I need to extract first word from it and convert it to lowercase:

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

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

Let's focus only on valid PascalCase identifiers (without any other characters, numbers and always starting with capital letter).

What would be the simple and clean solution for my problem?

I've tried

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

but it removes all uppercase letters, while I need to preserve them.

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) }
}

Something like:

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

The Groovy find operator ( =~ ) seems to do the job nicely:

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

The inject method can be used to accumulate characters until the second capital letter is encountered:

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM