PascalCase中的第一个单词为小写

时间:2016-08-26 11:30:24

标签: groovy pascalcasing

我有一个包含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 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

类似的东西:

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

答案 2 :(得分:2)

Groovy查找运算符(=~)似乎很好地完成了这项工作:

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

答案 3 :(得分: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'