【问题标题】:Put something after the nth digit, rather than nth character?在第 n 个数字之后放置一些东西,而不是第 n 个字符?
【发布时间】:2011-08-10 16:03:15
【问题描述】:

我正在开发 PHP 中类似 SSN 的数字的自动完成功能。因此,如果用户搜索“123”,它应该会找到数字 444123555。我想将结果加粗,因此,444<b>123</b>555。但是,我想将其格式化为 SSN - 从而创建 444-<b>12-3</b>555

有什么办法可以说“将破折号放在第 n 个数字之后”吗?因为我不想要第 n 个字符,只想要第 n 个数字 - 如果我可以说“在第三个数字和第五个数字之后放一个破折号,忽略像 之类的非数字字符”,那就太棒了。这在正则表达式中可行吗?

或者有什么不同的方法让我在这里逃脱?

【问题讨论】:

  • 您是否已经有了搜索结果,或者正在获取问题的搜索结果部分?如果您已经有搜索功能,请描述它是如何匹配的。这也是匹配突出显示的正确部分所必需的。
  • 我在输入中修剪破折号并在数据库中的破折号修剪列中搜索。

标签: php regex


【解决方案1】:

只需遍历字符串并检查每个字符是否为数字,然后计算数字。

这将比正则表达式快得多,即使正则表达式在这里是一个可行的解决方案(我不相信它是)。

【讨论】:

  • 嗯,实际上有一个非常简单(而且很可能更快)的正则表达式可以完全满足您的需求。请参阅下面的答案。
【解决方案2】:

这将完全满足您的要求:

$str = preg_replace('/^ ((?:\D*\d){3}) ((?:\D*\d){2}) /x', '$1-$2-', $str);

(?:\D*\d) 将匹配任意数量的非数字,然后是数字。通过重复 n 次,您匹配 n 个数字,“忽略”其他所有内容。

【讨论】:

    【解决方案3】:

    这是一个使用 Platinum Azure 建议的迭代方法的简单函数:

    function addNumberSeparator($numString, $n, $separator = '-')
    {
        $numStringLen = strlen($numString);
    
        $numCount = 0;
        for($i = 0; $i < $numStringLen; $i++)
        {
            if(is_numeric($numString[$i]))
            {
                $numCount++;
                //echo $numCount . '-' . $i;
            }
    
            if($numCount == $n)
                return substr($numString, 0, $i + 1) . $separator .     substr($numString, $i + 1);
        }
    }
    
    $string = '444<b>123</b>555';
    
    $string = addNumberSeparator($string, 3);
    $string = addNumberSeparator($string, 5);
    
    echo $string;
    

    这会输出以下内容:

    4x<b>x123</b>555
    

    当然,这仅适用于非数字分隔符。不是最优美的代码,但它应该给你一个开始!

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      如果你想得到格式化的数字和周围的文字:

      <?php
      preg_match("/(.*)(\d{3})(12)(3)(.*)/", "assd444123666as555", $match);
      $str = $match[1];
      if($match[2]!=="") $str.=$match[2]."-<b>";
      $str.=$match[3]."-".$match[4]."</b>";
      if($match[5]!=="") $str.=$match[5];
      echo $str;
      ?>
      

      如果只有格式化数字:

      <?php
      preg_match("/(.*)(\d{3})(12)(3)(.*)/", "as444123666as555", $match);
      $str = "";
      if($match[2]!=="") $str.=$match[2]."-<b>";
      $str.=$match[3]."-".$match[4]."</b>";
      echo $str;
      ?>
      

      对不起,这有点模棱两可。

      【讨论】:

      • 你刚刚告诉我如何包围中间的三个数字,不管它们是什么?那么如果 123 在字符串的开头呢?还是从第 4 个位置开始?编辑:你的编辑甚至做得不好。您似乎没有理解问题的含义 - 它是正确插入破折号无论搜索结果在哪里。它并不总是会是中间三个。我不觉得这是模棱两可的。
      • 搜索字符串周围的粗体是什么?
      • 你想怎么做...?把它放在这个符号之间:“*”?那么,究竟应该输出什么?这? pastebin.com/LaQJYakQ
      • 在我的屏幕上,我看到 444123555 和 123 为粗体。在它之前是 *s 因为解析器似乎坏了。在这种情况下,我将用&lt;b&gt;123&lt;/b&gt; 替换数字。然后我想正确地断字。很抱歉,它依赖于格式来清晰。
      • 好的,现在我想我什么都明白了。抱歉有问题...我编辑了我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多