将严格格式为大写字母和数字的字符串分成两半

问题描述 投票:0回答:6

我有几个格式的字符串

AA11
AAAAAA1111111
AA1111111

我需要分离字符串的字母和数字部分。

php string split text-extraction text-parsing
6个回答
8
投票

如果它们都是一系列字母,后跟一系列数字,没有非字母数字字符,那么 sscanf() 可能比 regexp 更高效

$example = 'AAA11111';
list($alpha,$numeric) = sscanf($example, "%[A-Z]%d");

var_dump($alpha);
var_dump($numeric);

1
投票

这是一个使用

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"

1
投票

您可以添加一项额外的检查,而不是立即使用 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
}

编辑:显然我的答案没有给出表现更好的证据,这就是为什么我做了一个测试,产生了以下结果:

  1. preg_split 花了 5.3319189548492 秒
  2. sscanf 花费了 3.4432129859924 秒

答案应该是

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, "%[A-Z]%[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';

0
投票

preg_split
应该可以很好地完成工作。

preg_split('/(\w+)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE);

preg 库在处理字符串方面出奇地高效,因此我认为它比使用更原始的字符串函数手写的任何内容都更高效。但请亲自测试一下。


0
投票

这似乎有效,但是当您尝试传递类似“111111”之类的内容时,却不起作用。

在我的应用程序中,我期待几种场景,而似乎起作用的就是这个

$referenceNumber = "AAA12132";
$splited = preg_split('/(\d+)/', $referenceNumber, -1, PREG_SPLIT_DELIM_CAPTURE);
var_dump($splited);

注意

  1. 获取一个包含 2 个元素的数组,这意味着第 0 个索引是 alpha,第 1 个索引是 numerics
  2. 获取仅包含 1 个元素的数组,意味着第 0 个元素是 numeric 并且没有字母。
  3. 如果您获得超过 2 个数组项,则您的字符串必须采用“AAA1323SDC”格式

因此,鉴于上述内容,您可以根据您的用例来使用它。

干杯!


0
投票

我怀疑在比较

sscanf()
preg_split()
时,性能是否会成为一个重要的关注点。这两个函数之间最有价值的区别是
sscanf()
能够将数字子字符串转换为整数 - 这在类型严格性至关重要的(真正专业的)应用程序中非常方便。

如果两个字符串类型值可接受,则在最后出现的字母之后的零宽度位置进行拆分。您可以根据您的业务需求安全地将拆分限制为最大

2

以下所有片段的演示

$twoStringArray = preg_split('/[A-Z]+\K/', $input, 2);
var_export($twoStringArray);
// ['AAA', '111']

可以通过两种方式访问

sscanf()
的输出。

如果只有两个参数传递给函数,则

sscanf()
将返回捕获值的数组。

var_export(
    sscanf($input, '%[A-Z]%d')
);
// ['AAA', 111]

如果在前两个参数之后指定引用变量,则

sscanf()
将填充尽可能多的变量并返回成功捕获子字符串的数量。请注意,引用变量是在返回计数值之前填充的。

$result[] = sscanf($input, '%[A-Z]%d', $result[], $result[]);
var_export($result);
// ['AAA', 111, 2]
© www.soinside.com 2019 - 2024. All rights reserved.