php - 使用预定义模式匹配号码

标签 php mysql regex search

我有一个问题,我已经思考了一段时间,但未能找到最佳解决方案。

该应用程序适用于一家根据号码模式以不同价格销售特殊电话号码的公司。

所以用户有一个数字库存。并使用某种约定定义模式。例如:

  • (ABCDEFG) 表示具有序列的数字,例如 (1234567,或 2345678 等...)。
  • (ZYX-ZYXW) 代表一个数字,例如 (654-6543)。

当客户取号时,将号码与所匹配的图案进行匹配,当匹配到图案时,该号码将按匹配图案的价格收取费用。

我的想法集中在三种可能的解决方案上:

  1. 我试着想出正则表达式。但不确定是否可以 工作。
  2. 另一种解决方案是遍历每种可能性 对于每个模式并将其与购买的号码进行匹配。但是我 我确信这在性能方面会过于昂贵。
  3. 最后我想在用户添加一个时保存所有可能的数字 模式,以便当客户想要购买新号码时, 应用程序不搜索模式,而是搜索实际数字。这 当用户添加模式时性能瓶颈的方式 (这比客户选择号码的频率低得多)。

你们对我应该使用哪种方法有什么建议吗?非常感谢任何提示。

编辑:

我对收到的回复感到非常高兴。他们都很有启发性,但是到目前为止还不能解决我的问题。现实世界的场景将具有以下条件:

  • 一些模式将遵循某种数字顺序(顺序或非顺序),例如:ABCDEFG=1234567 或 ACEGECA=2468642。
  • 一些模式将基于数字的重复,例如:xyxyxyx=1919191 或 xyxzxyx=2829282。我想在某种程度上我们可以将这个条件包含在上面的条件中。
  • 有些模式会有硬编码数字,比如 ABC0ABC 或 123xyxy
  • 模式的可能性没有限制。

到目前为止,所有提出的方法都有其自身的局限性。我还在想,所以如果你有什么有用的点击,请与我分享!

最佳答案

一个想法。 demo

$number = '987-9876';
$suffix = <<<'EOD'
0123456789 ABCDEFG 10 ABCABCD 15
9876543210 GFEDCBA 8 DCBDCBA 13
EOD;

$pattern = <<<'EOD'
~
\A (?<number>(\d{3})-?(\d{4})) \R 
(?|
    \d*? # rectus
    (?|
        \2 \3 \d*
        [ ] (?<format> ABCDEFG ) [ ] (?<price>\d+)
      |
        (?=\3) \2 \d*
        (?> [ ] [A-Z]+ [ ] \d+)*? # other formats until the good one
        [ ] ( ABCABCD ) [ ] (\d+)
    )
  |
    .* \R \d*? # inversus
    (?|
        \2 \3 \d*
        [ ] ( GFEDCBA ) [ ] (\d+)
      |
        (?=\3) \2 \d*
        (?> [ ] [A-Z]+ [ ] \d+)*?
        [ ] ( DCBDCBA ) [ ] (\d+)
    )
)
~x
EOD;

if (preg_match($pattern, $number . PHP_EOL . $suffix, $m))
    echo 'number: ' . $m['number'] . PHP_EOL . 'format: ' . $m['format'] . PHP_EOL
       . 'price: ' . $m['price'];

其他方法 (可能是性能最好的)

特殊号码有限。您可以生成并使用包含所有特殊数字的多维数组,如下所示:

$speNum = [
    'ABCDEFG' => [ '1234567', '2345678', '3456789' ],
    'GFEDCBA' => [ '9876543', '8765432', '7654321' ],
    'ABCABCD' => [ '1231234', '2342345' ... 
];

$prices = [ 'ABCDEFG' => 10, 'ABCABCD' => 15, 'GFEDCBA' => 8 ...];

然后使用一个简单的foreach,测试数字是否在数组中:

foreach ($speNum as $format => $nums) {
    if (in_array($number, $nums)) {
        echo 'number: ' . $number . PHP_EOL . 'format: ' . $format . PHP_EOL
           . 'price: ' . $prices[$format];
        break;
    }
}

注意:对于第二种方法(为什么不是第一种方法),删除之前的连字符。这种方法的主要优点是您可以轻松地将其扩展到其他类型的模式。请注意,您可以对数据库执行相同的操作。

关于php - 使用预定义模式匹配号码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32160666/

相关文章:

mysql - 如何更改 where 条件以从其他数据库表中读取数字?

javascript - 如何在不影响标记的情况下替换 html 文档中的文本?

java - 字符串中所有数字的动态递增

java - 如何替换引号外的单词

php - 格式化日期,日期的序号后缀

javascript - 在子文件夹中添加 css 链接,php 扩展文件

php - 当执行时间超过指定的时间限制时,是否可以终止代码部分?

PHP 文件缓存不能在循环中工作

php - 查询是从 PHPMYAdmin 而不是从 PHP 插入的

php - INSERT 和 UPDATE 语句将错误数据传递到数据库