У меня есть несколько строк формата
AA11 AAAAAA1111111 AA1111111
Каков наилучший (наиболее эффективный) способ разделения алфавитных и числовых компонентов строки?
Если они все серии альфа, а затем ряд числовых, без несимвольных символов, то sscanf () , вероятно, более эффективен, чем regexp
$example = 'AAA11111'; list($alpha,$numeric) = sscanf($example, "%[AZ]%d"); var_dump($alpha); var_dump($numeric);
preg_split
должен отлично выполнять работу.
preg_split('/(\w+)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE);
Библиотека preg удивительно эффективна при обработке строк, поэтому я бы предположил, что она более эффективна, чем все, что вы можете написать вручную, используя более примитивные строковые функции. Но сделайте тест и убедитесь сами.
Вот пример работы с preg_split()
:
$strs = array( 'AA11', 'AAAAAA1111111', 'AA1111111'); foreach( $strs as $str) foreach( preg_split( '/([A-Za-z]+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $temp) var_dump( $temp);
Эти результаты :
string(2) "AA" string(2) "11" string(6) "AAAAAA" string(7) "1111111" string(2) "AA" string(7) "1111111"
Вместо использования RegEx сразу вы можете добавить одну дополнительную проверку, например:
if (ctype_alpha($testcase)) { // Return the value it's only letters } else if(ctype_digit($testcase)) { // Return the value it's only numbers } else { //RegEx your string to split nums and alphas }
EDIT: Очевидно, мой ответ не дал доказательств, которые будут работать лучше, поэтому я сделал тест, который дал следующий результат:
И ответ должен был быть sscanf
Вот код, который дал результат:
$string = "AAAAAAAAAA111111111111111"; $count = 1000000; function prSplit($string) { return preg_split( '/([A-Za-z]+)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); } function sScanfTest($string) { return sscanf($string, "%[AZ]%[0-9]"); } function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } $startTime1 = microtime_float(); for($i=0; $i<$count; ++$i) { prSplit($string); } $time1 = microtime_float() - $startTime1; echo '1. preg_split took '.$time1.' seconds<br />'; $startTime2 = microtime_float(); for($i=0; $i<$count; ++$i) { sScanfTest($string); } $time2 = microtime_float() - $startTime2; echo '2. sscanf took '.$time2.' seconds';