Разделите слово camelCase на слова с помощью PHP preg match (регулярное выражение)


как бы я пошел о разделении слова:

oneTwoThreeFour

в массив, так что я могу сделать:

one Two Three Four

С preg_match ?

Я устал это, но это просто дает все слово

$words = preg_match("/[a-zA-Z]*(?:[a-z][a-zA-Z]*[A-Z]|[A-Z][a-zA-Z]*[a-z])[a-zA-Z]*b/", $string, $matches)`;
12 55

12 ответов:

вы также можете использовать preg_match_all как:

preg_match_all('/((?:^|[A-Z])[a-z]+)/',$str,$matches);

объяснение:

(        - Start of capturing parenthesis.
 (?:     - Start of non-capturing parenthesis.
  ^      - Start anchor.
  |      - Alternation.
  [A-Z]  - Any one capital letter.
 )       - End of non-capturing parenthesis.
 [a-z]+  - one ore more lowercase letter.
)        - End of capturing parenthesis.

можно использовать preg_split как:

$arr = preg_split('/(?=[A-Z])/',$str);

видеть

Я в основном разделяю входную строку непосредственно перед прописной буквой. Регулярное выражение используется (?=[A-Z]) соответствует точке непосредственно перед прописной буквой.

я знаю, что это старый вопрос с принятым ответом, но ИМХО есть лучшее решение:

<?php // test.php Rev:20140412_0800
$ccWord = 'NewNASAModule';
$re = '/(?#! splitCamelCase Rev:20140412)
    # Split camelCase "words". Two global alternatives. Either g1of2:
      (?<=[a-z])      # Position is after a lowercase,
      (?=[A-Z])       # and before an uppercase letter.
    | (?<=[A-Z])      # Or g2of2; Position is after uppercase,
      (?=[A-Z][a-z])  # and before upper-then-lower case.
    /x';
$a = preg_split($re, $ccWord);
$count = count($a);
for ($i = 0; $i < $count; ++$i) {
    printf("Word %d of %d = \"%s\"\n",
        $i + 1, $count, $a[$i]);
}
?>

обратите внимание, что это регулярное выражение (например, codaddict '/(?=[A-Z])/' решение-которое работает как шарм для хорошо сформированных слов camelCase), соответствует только a позиция внутри строки и не потребляет текст вообще. Это решение имеет дополнительное преимущество, что оно также работает правильно для не очень хорошо сформированных псевдо-camelcase слов, таких как:StartsWithCap и: hasConsecutiveCAPS.

вход:

oneTwoThreeFour
StartsWithCap
hasConsecutiveCAPS
NewNASAModule

выход:

Word 1 of 4 = "one"
Word 2 of 4 = "Two"
Word 3 of 4 = "Three"
Word 4 of 4 = "Four"

Word 1 of 3 = "Starts"
Word 2 of 3 = "With"
Word 3 of 3 = "Cap"

Word 1 of 3 = "has"
Word 2 of 3 = "Consecutive"
Word 3 of 3 = "CAPS"

Word 1 of 3 = "New"
Word 2 of 3 = "NASA"
Word 3 of 3 = "Module"

отредактировано: 2014-04-12: модифицированных регулярное выражение, скрипт и тестовые данные для правильного разделения:"NewNASAModule" case (в ответ на комментарий rr).

функциональная версия ответа @ridgerunner.

/**
 * Converts camelCase string to have spaces between each.
 * @param $camelCaseString
 * @return string
 */
function fromCamelCase($camelCaseString) {
        $re = '/(?<=[a-z])(?=[A-Z])/x';
        $a = preg_split($re, $camelCaseString);
        return join($a, " " );
}

хотя ответ ridgerunner отлично работает, он, похоже, не работает со всеми подстроками caps, которые появляются в середине предложения. Я использую следующие и, кажется, иметь дело с ними просто хорошо:

function splitCamelCase($input)
{
    return preg_split(
        '/(^[^A-Z]+|[A-Z][^A-Z]+)/',
        $input,
        -1, /* no limit for replacement count */
        PREG_SPLIT_NO_EMPTY /*don't return empty elements*/
            | PREG_SPLIT_DELIM_CAPTURE /*don't strip anything from output array*/
    );
}

в некоторых случаях тест:

assert(splitCamelCase('lowHigh') == ['low', 'High']);
assert(splitCamelCase('WarriorPrincess') == ['Warrior', 'Princess']);
assert(splitCamelCase('SupportSEELE') == ['Support', 'SEELE']);
assert(splitCamelCase('LaunchFLEIAModule') == ['Launch', 'FLEIA', 'Module']);
assert(splitCamelCase('anotherNASATrip') == ['another', 'NASA', 'Trip']);
$string = preg_replace( '/([a-z0-9])([A-Z])/', " ", $string );

трюк-это повторяемый шаблон $1 $2$1 $2 или нижний верхний верхний и т. д.... например файл HelloWorld = $1 соответствует "привет", $2 игр между "ж" и $1 матчей "мир" снова, так что в короткое вы получаете $1 $2$1 или "Здравствуй, Мир!", играм это как $2$1 $2$1 или опять "здравствуй, мир". Затем вы можете опустить их в верхний регистр первого слова или взорвать их на пробел, или использовать _ или какой-либо другой символ, чтобы держать их отдельно.

коротко и просто.

Я взял код cool guy Ridgerunner (выше) и превратил его в функцию:

echo deliciousCamelcase('NewNASAModule');

function deliciousCamelcase($str)
{
    $formattedStr = '';
    $re = '/
          (?<=[a-z])
          (?=[A-Z])
        | (?<=[A-Z])
          (?=[A-Z][a-z])
        /x';
    $a = preg_split($re, $str);
    $formattedStr = implode(' ', $a);
    return $formattedStr;
}

это вернется: New NASA Module

другой вариант соответствует /[A-Z]?[a-z]+/ - Если вы знаете, что ваш вход находится в правильном формате, он должен работать хорошо.

[A-Z]? соответствует прописной букве (или ничего). [a-z]+ будет соответствовать все следующие строчные буквы, до следующего матча.

рабочий пример:http://www.ideone.com/MKYkX

может быть, мой вопрос может помочь вам, Я спросил то же самое вчера, но о Java

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

вы можете разделить на "скольжение" из нижнего регистра в верхний таким образом:

$parts = preg_split('/([a-z]{1})[A-Z]{1}/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);        
//PREG_SPLIT_DELIM_CAPTURE to also return bracketed things
var_dump($parts);

досадно вам придется перестраивать слова из каждой соответствующей пары элементов в $parts

надеюсь, что это помогает

прежде всего codaddict спасибо за ваш шаблон, это очень помогло!

Мне нужно было решение, которое работает в случае, если предлог' a ' существует:

например, thisIsACamelcaseSentence.

Я нашел решение в выполнении двухэтапного preg_match и сделал функцию с некоторыми опциями:

/*
 * input: 'thisIsACamelCaseSentence' output: 'This Is A Camel Case Sentence'
 * options $case: 'allUppercase'[default] >> 'This Is A Camel Case Sentence'
 *                'allLowerCase'          >> 'this is a camel case sentence'
 *                'firstUpperCase'        >> 'This is a camel case sentence'
 * @return: string
 */

function camelCaseToWords($string, $case = null){
    isset($case) ? $case = $case : $case = 'allUpperCase';

    // Find first occurances of two capitals
    preg_match_all('/((?:^|[A-Z])[A-Z]{1})/',$string, $twoCapitals);

    // Split them with the 'zzzzzz' string. e.g. 'AZ' turns into 'AzzzzzzZ'
    foreach($twoCapitals[0] as $match){
        $firstCapital = $match[0];
        $lastCapital = $match[1];
        $temp = $firstCapital.'zzzzzz'.$lastCapital;
        $string = str_replace($match, $temp, $string);  
    }

    // Now split words
    preg_match_all('/((?:^|[A-Z])[a-z]+)/', $string, $words);

    $output = "";
    $i = 0;
    foreach($words[0] as $word){

            switch($case){
                case 'allUpperCase':
                $word = ucfirst($word);
                break;

                case 'allLowerCase': 
                $word = strtolower($word);
                break;

                case 'firstUpperCase':
                ($i == 0) ? $word = ucfirst($word) : $word = strtolower($word);
                break;                  
            }

            // remove te 'zzzzzz' from a word if it has
            $word = str_replace('zzzzzz','', $word);    
            $output .= $word." ";
            $i++;
    }
    return $output; 
}

Не стесняйтесь использовать его, и в случае, если есть "более простой" способ сделать это в один шаг, пожалуйста, прокомментируйте!

полная функция на основе @codaddict ответ:

function splitCamelCase($str) {
    $splitCamelArray = preg_split('/(?=[A-Z])/', $str);

    return ucwords(implode($splitCamelArray, ' '));
}