Отделить текст от цифр

243
21 октября 2017, 18:51

Пробую отделить текст от цифр, но ничего не выходит (результат представленного ниже регулярного выражения пуст)

print_r(divide_sample('центр25'));
private final function divide_sample($sample_number)
{
    preg_match("/([a-zA-Zа-яА-Я]+)([0-9]+)/", $sample_number, $pieces);
    return $pieces;
}

Ожидаемый выход: ['центр', '25']

Фиддл - http://tpcg.io/s5vdhO

Передаваться функции всегда будет или текстЧисло или числоТекст. Смешанных строк быть не может. Как быть? Может есть другие варианты - не регулярные выражения? Вопрос не дубликат. И название у вопроса реально удобнее выгуглить.

Answer 1

Добавлю свой вариант в коллекцию ответов:

function divide_sample($str, $out = []) {
    preg_match_all('~(\d+)?(?(1)|\D+)~', $str, $arr);
    foreach ($arr[0] as $item) {
        ctype_digit($item) ? $out['int'] = $item : $out['txt'] = $item;
    }
    return $out;
}

В результате функция вернёт ассоциативный массив $out с ключами int и txt, в которых данные будут соответствовать их названиям.

Далее можно с помощью ф-ции extract() экспортировать этот массив в текущую область видимости, после чего в скрипте станут доступны переменные $int и $txt.

И даже если поменять в вызове функции divide_sample() местами текст с числом - значения этих переменных всё равно будут корректными. Примеры использования:

extract(divide_sample('25центр'));
echo $int . ' - ' . $txt . '<br />'; // 25 - центр
extract(divide_sample('центр25'));
echo $int . ' - ' . $txt;            // 25 - центр
Answer 2

Проблема в отсутствии юникодного флага: https://ideone.com/uWO8vT

<?php
$sample_number = 'центр25';
preg_match("/([a-zA-Zа-яА-Я]+)([0-9]+)/u", $sample_number, $pieces);
print_r($pieces);
Answer 3

в копилку вариант:

 array_filter(preg_split("/(\d+)/",$str, 2, PREG_SPLIT_DELIM_CAPTURE));

если не будет строк вида центр0, то можно использовать прямо так. Если 0 будет встречаться, то callback-надо писать.

тест:

foreach(["центр25", "25центр", "0str"] as $str){
    $data = preg_split("/(\d+)/",$str, 2, PREG_SPLIT_DELIM_CAPTURE);   
    print_r(array_filter($data));    
}

результат

Array
(
    [0] => центр
    [1] => 25
)
Array
(
    [1] => 25
    [2] => центр
)
Array
(
    [2] => str
)
Answer 4

Используйте отрицание.

<?php
print_r(divide_sample('центр25'));
function divide_sample($sample_number)
{
    preg_match("/([^\d]+)(\d+)/", $sample_number, $pieces);
    return [$pieces[1], $pieces[2]];
}

http://tpcg.io/aZUPLO

В вашем варианте не находится ничего потому что регулярки не понимают уникод если это явно не запрошено. Например, такая регулярка с флагом u будет работать как вы хотите:

/([a-zA-Zа-яА-Я]+)([0-9]+)/u 
Answer 5

Может есть другие варианты - не регулярные выражения?

function divide_sample($sample_number)
{
    $str = trim($sample_number, '1234567890');
    if ($str == '') {
        return [$sample_number, ''];
    } else if (($pos = strpos($sample_number, $str)) === 0) {
        return [$str, substr($sample_number, strlen($str))];
    } else {
        return [substr($sample_number, 0, $pos), substr($sample_number, $pos)];
    }
}
foreach (["центр25", "25центр", "0str", "256", "центр", "25str25"] as $str) {
    print_r(divide_sample($str));  
}

Результат:

Array
(
    [0] => центр
    [1] => 25
)
Array
(
    [0] => 25
    [1] => центр
)
Array
(
    [0] => 0
    [1] => str
)
Array
(
    [0] => 256
    [1] => 
)
Array
(
    [0] => центр
    [1] => 
)
Array
(
    [0] => 25
    [1] => str25
)

Тест http://sandbox.onlinephpfunctions.com/code/d2e9fb1afb528033ea4a7ed43941c0c6a8ed4fbe

Answer 6

А если вот так?

print_r(divide_sample('центр25'));
function divide_sample($sample_number)
{
    return preg_split('/(,?\s+)|((?<=[а-яa-z])(?=\d))|((?<=\d)(?=[а-яa-z]))/ui', $sample_number);
}
READ ALSO
Передача значения select ajax запросом

Передача значения select ajax запросом

ЗдравствуйтеЕсть select в form и div который должен принять ответ от сервера

273
Ajax как вернуть ошибку с сервера

Ajax как вернуть ошибку с сервера

Добрый, день помогите пожалуйста, отправляю на сервер комментарий пользователя, средствами ajax, скрипту answerphp

318