PHP : non-preg_match 版本: preg_match("/[^a-z0-9]/i", $a, $match)?
PHP : non-preg_match version of: preg_match("/[^a-z0-9]/i", $a, $match)?
假定字符串是:
$a = "abc-def"
if (preg_match("/[^a-z0-9]/i", $a, $m)){
$i = "i stopped scanning '$a' because I found a violation in it while
scanning it from left to right. The violation was: $m[0]";
}
echo $i;
上面的例子:应该指出“-”是违规行为。
我想知道是否有 non-preg_match 方法可以做到这一点。
我可能会 运行 基准测试,如果有 non-preg_match 方法可以做到这一点,也许 1000 或 100 万 运行s,看看哪个更快、更有效。
在基准测试中,“$a”会更长。
确保它不会尝试扫描整个“$a”并确保它在检测到“$a”中的违规行为时立即停止
根据我在 Internet 上看到的信息,preg_match 在找到第一个匹配项时停止。
更新:
这是基于 "bishop" 给出的答案,并且很可能很快(很快)被选为有效答案。
我稍微修改了一下,因为我只希望它报告违规者角色。但我也评论说 line out 所以 benchmark 可以 运行 没有纠缠。
让我们 运行 基于那个答案得到 100 万 运行。
$start_time = microtime(TRUE);
$count = 0;
while ($count < 1000000){
$allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$input = 'abc-def';
$validLen = strspn($input, $allowed);
if ($validLen < strlen($input)){
#echo "violation at: ". substr($input, $validLen,1);
}
$count = $count + 1;
};
$end_time = microtime(TRUE);
$dif = $end_time - $start_time;
echo $dif;
结果是:0.606614112854
(60% 秒)
让我们用preg_match方法来做吧。
我希望一切都一样。 (和公平)..
(我这样说是因为 preg_match 中有 ^ 字符)
$start_time = microtime(TRUE);
$count = 0;
while ($count < 1000000){
$input = 'abc-def';
preg_match("/[^a-z0-9]/i", $input, $m);
#echo "violation at:". $m[0];
$count = $count + 1;
};
$end_time = microtime(TRUE);
$dif = $end_time - $start_time;
echo $dif;
我在参考术语 "difference" 时使用 "dif"。
"dif" 是.. 1.1145210266113
(比整整一秒多了 11%)
(如果是 1.2,则意味着它比 php 方式慢 2 倍)
您想在给定范围内找到 first 字符 not 的位置,而不使用正则表达式?你可能想要 strspn
or its complement strcspn
:
$allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$input = 'abc-def';
$validLen = strspn($input, $allowed);
if (strlen($input) !== $validLen) {
printf('Input invalid, starting at %s', substr($input, $validLen));
} else {
echo 'Input is valid';
}
输出Input invalid, starting at -def
。 See it live.
strspn
(及其补充)非常古老,非常明确(甚至 POSIX)。标准实现针对此任务进行了优化。 PHP 只是利用该平台实现,所以 PHP 也应该很快。
假定字符串是:
$a = "abc-def"
if (preg_match("/[^a-z0-9]/i", $a, $m)){
$i = "i stopped scanning '$a' because I found a violation in it while
scanning it from left to right. The violation was: $m[0]";
}
echo $i;
上面的例子:应该指出“-”是违规行为。
我想知道是否有 non-preg_match 方法可以做到这一点。
我可能会 运行 基准测试,如果有 non-preg_match 方法可以做到这一点,也许 1000 或 100 万 运行s,看看哪个更快、更有效。
在基准测试中,“$a”会更长。 确保它不会尝试扫描整个“$a”并确保它在检测到“$a”中的违规行为时立即停止
根据我在 Internet 上看到的信息,preg_match 在找到第一个匹配项时停止。
更新:
这是基于 "bishop" 给出的答案,并且很可能很快(很快)被选为有效答案。
我稍微修改了一下,因为我只希望它报告违规者角色。但我也评论说 line out 所以 benchmark 可以 运行 没有纠缠。
让我们 运行 基于那个答案得到 100 万 运行。
$start_time = microtime(TRUE);
$count = 0;
while ($count < 1000000){
$allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$input = 'abc-def';
$validLen = strspn($input, $allowed);
if ($validLen < strlen($input)){
#echo "violation at: ". substr($input, $validLen,1);
}
$count = $count + 1;
};
$end_time = microtime(TRUE);
$dif = $end_time - $start_time;
echo $dif;
结果是:0.606614112854
(60% 秒)
让我们用preg_match方法来做吧。
我希望一切都一样。 (和公平).. (我这样说是因为 preg_match 中有 ^ 字符)
$start_time = microtime(TRUE);
$count = 0;
while ($count < 1000000){
$input = 'abc-def';
preg_match("/[^a-z0-9]/i", $input, $m);
#echo "violation at:". $m[0];
$count = $count + 1;
};
$end_time = microtime(TRUE);
$dif = $end_time - $start_time;
echo $dif;
我在参考术语 "difference" 时使用 "dif"。
"dif" 是.. 1.1145210266113
(比整整一秒多了 11%)
(如果是 1.2,则意味着它比 php 方式慢 2 倍)
您想在给定范围内找到 first 字符 not 的位置,而不使用正则表达式?你可能想要 strspn
or its complement strcspn
:
$allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$input = 'abc-def';
$validLen = strspn($input, $allowed);
if (strlen($input) !== $validLen) {
printf('Input invalid, starting at %s', substr($input, $validLen));
} else {
echo 'Input is valid';
}
输出Input invalid, starting at -def
。 See it live.
strspn
(及其补充)非常古老,非常明确(甚至 POSIX)。标准实现针对此任务进行了优化。 PHP 只是利用该平台实现,所以 PHP 也应该很快。