组合正则表达式以将camelCase字符串拆分为单词


Combine regular expressions for splitting camelCase string into words

我使用@ridgerrunner在这个问题中建议的解决方案,成功地实现了一个将camel大小写转换为单词的函数:

使用php preg_match(正则表达式)将camelBase单词拆分为单词

然而,我也想处理这样的嵌入式设备:

"hasABREVIATIONEmbedded"翻译为"Has ABREVIATION Embedded

我想出了这个解决方案:

    <?php 
    function camelCaseToWords($camelCaseStr)
    {
        // Convert: "TestASAPTestMore" to "TestASAP TestMore"
        $abreviationsPattern = '/' . // Match position between UPPERCASE "words"
            '(?<=[A-Z])' . // Position is after group of uppercase,
            '(?=[A-Z][a-z])' . // and before group of lowercase letters, except the last upper case letter in the group.
            '/x';
        $arr = preg_split($abreviationsPattern, $camelCaseStr);
        $str = implode(' ', $arr);
        // Convert "TestASAP TestMore" to "Test ASAP Test More"
        $camelCasePattern = '/' . // Match position between camelCase "words".
            '(?<=[a-z])' . // Position is after a lowercase,
            '(?=[A-Z])' . // and before an uppercase letter.
            '/x';
        $arr = preg_split($camelCasePattern, $str);
        $str = implode(' ', $arr);
        $str = ucfirst(trim($str));
        return $str;
    }
    $inputs = array(
    'oneTwoThreeFour',
    'StartsWithCap',
    'hasConsecutiveCAPS',
    'ALLCAPS',
    'ALL_CAPS_AND_UNDERSCORES',
    'hasABREVIATIONEmbedded',
    );
    echo "INPUT";
    foreach($inputs as $val) {
        echo "'" . $val . "' translates to '" . camelCaseToWords($val). "''n";
    }

输出为:

    INPUT'oneTwoThreeFour' translates to 'One Two Three Four'
    'StartsWithCap' translates to 'Starts With Cap'
    'hasConsecutiveCAPS' translates to 'Has Consecutive CAPS'
    'ALLCAPS' translates to 'ALLCAPS'
    'ALL_CAPS_AND_UNDERSCORES' translates to 'ALL_CAPS_AND_UNDERSCORES'
    'hasABREVIATIONEmbedded' translates to 'Has ABREVIATION Embedded'

它按预期工作。

我的问题是:我可以组合两个正则表达式$abrevisionsPattern和camelCasePattern吗这样我就可以避免运行preg_split()函数两次了?

这些谜题总是很有趣的;我已经把案例缩小到两个:

  1. 检测以大写字母和小写字母开头的单词(但前面没有单词边界或主题开头)-(?<!'b)[A-Z][a-z]+

  2. 检测从小写到大写的转换-(?<=[a-z])[A-Z]

    function camelFix($str)
    {
        return preg_replace_callback('/(?<!'b)[A-Z][a-z]+|(?<=[a-z])[A-Z]/', function($match) {
            return ' '. $match[0];
        }, $str);
    }
    

它适用于您提供的输入;它可能会出现我没有预见到的失败情况:)