【问题标题】:Function calling itself based upon regular expression基于正则表达式调用自身的函数
【发布时间】:2018-02-16 01:21:05
【问题描述】:

我需要创建一个 UID,并且考虑到前几个组件 - 句点之间的部分 (.) - 我创建了一个函数来执行此操作。生成此 UID 的规则是,它不能在组件中包含任何前导零,除非它在它自己的组件中是零。因此:1.2.6.4.0.123.6653 很好,而 1.2.6.4.0123.6653 不是。

我的功能如下:

function genUid($type, $serverId){
    $prefix = '1.2.3.3680043.19.1944';
    $ts = date('YmdHis'); 
    $uniqid = substr(hexdec(uniqid()),-7);

    $uid = $prefix . '.' . $serverId . $type . '.' . $ts . '.' . $uniqid;

    // the uniqid can't start with a leading 0 
    //$re = '/\.0\d]/';
    $re = '/\.0[0-9]/';
    preg_match($re, $uid, $matches);
    if(count($matches)){
        genUid($type, $serverId);
    }
    return $uid;
}

我只是通过调用它

for($i=0; $i<100000; $i++){
    $id = genUid('3', '1');
    echo $id . '<br>';
}

echo '<hr>Longest run circa 86,000';

当我运行脚本时,它会显示 100,000 个 UID。为了检查,我搜索了一个句点,然后是一个零,然后是任何其他数字,从 1 到 9。一切看起来都很好,直到我想检查“.00”,在这种情况下,似乎总是只生成一个。

如您所见,如果该函数发现它创建的 UID 与正则表达式 '/.0\d/' 匹配(我也尝试过 '/.0[0-9]/'看看它是否有任何区别,但它没有)但它似乎总是创建不超过一个 UID 不符合 UID 命名规则的 UID。

脚本没有超时(大约需要 5 秒才能完成),所以我有点困惑,为什么函数没有正确调用自身,或者我的正则表达式不正确?恕我直言,它永远不应该创建违反规则的 UID。

谁能给我一些指导,为什么会这样?

【问题讨论】:

    标签: php regex function


    【解决方案1】:

    递归调用时需要return函数的值:

    if(count($matches)){
        return genUid($type, $serverId);
    }
    

    在一般意义上,您似乎正在从由. 字符分隔的整数中创建一个 id。我可以建议gettimeofdaymt_rand 函数吗? gettimeofday 将以两个整数的形式为您提供当前时间(自纪元以来的秒数,秒中的微秒),mt_rand 将在两个值之间生成一个随机整数。通过使用整数,您无需检查前导零。像这样的东西可能对你有用:

    function genUid($type, $serverId){
        $prefix = '1.2.3.3680043.19.1944';
        $time = gettimeofday();
        $random = mt_rand(0, 9999999);
        $uid = sprintf(
            '%s.%d.%d.%d.%d.%d',
            $prefix,
            $serverId,
            $type,
            $time['sec'],
            $time['usec'],
            $random
        );
        return $uid;
    }
    

    请注意,uniqidmt_rand 不是加密安全的,如果您的项目需要这样做的话。

    【讨论】:

    • 看来是丢失的“返回”导致了我的问题。我刚刚执行了 500,000 次运行,并且没有一个 UID 有错误。非常感谢@astrangeloop! (感谢您的建议......我肯定会考虑它们并运行一些计时测试,看看它们对我现有代码的公平性 - 我听说运行正则表达式可能很耗时,所以加速任何事情都将是优势)
    猜你喜欢
    • 2011-05-14
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 2012-04-12
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多