【问题标题】:regex replace for decimals正则表达式替换小数
【发布时间】:2009-07-17 19:24:17
【问题描述】:

我正在尝试构建一个正则表达式,它将替换任何不符合以下格式的字符:

任意位数,然后可选(一个小数点,任意位数)

i.e.
123            // 123
123.123        // 123.123
123.123.123a   // 123.123123
123a.123       // 123.123

我在 php 中使用 ereg_replace,最接近我管理的工作正则表达式的是

ereg_replace("[^.0-9]+", "", $data);

这几乎是我所需要的(除了它允许任意数量的小数点)

i.e.
123.123.123a    // 123.123.123

我的下一次尝试是

ereg_replace("[^0-9]+([^.]?[^0-9]+)?", "", $data);

which was meant to translate as
[^0-9]+        // any number of digits, followed by
(              // start of optional segment
  [^.]?        // decimal point (0 or 1 times) followed by
  [^0-9]+      // any number of digits
)              // end of optional segment
?              // optional segment to occur 0 or 1 times

但这似乎只允许任意数量的数字,没有别的。

请帮忙

谢谢

【问题讨论】:

  • ereg_* 函数已弃用。请改用 preg_*。

标签: php regex


【解决方案1】:

试试这些步骤:

  1. 删除除0-9. 之外的任何字符
  2. 删除第一个小数点后面的任何.

这是一个带有正则表达式的实现:

$str = preg_replace('/[^0-9.]+/', '', $str);
$str = preg_replace('/^([0-9]*\.)(.*)/e', '"$1".str_replace(".", "", "$2")', $str);
$val = floatval($str);

另外一个只有一个正则表达式:

$str = preg_replace('/[^0-9.]+/', '', $str);
if (($pos = strpos($str, '.')) !== false) {
    $str = substr($str, 0, $pos+1).str_replace('.', '', substr($str, $pos+1));
}
$val = floatval($str);

【讨论】:

  • 谢谢,两者都像魅力一样工作-出于兴趣,您能否解释一下“$1”和“$2”-这些回溯来自正则表达式吗? (+1 票)
  • 是的,$1$2 是对 /^([0-9]*\.)(.*)/ 模式匹配的引用。 e 标志是将替换处理为要执行的表达式,并使用返回值作为替换。所以 '"$1".str_replace(".", "", "$2")' 被评估,$1$2 被替换为之前的匹配值。
  • 再次感谢,我想我需要去正则表达式学校;)
  • 如果你不太了解正则表达式,请使用第二个示例。两者都做同样的事情。
【解决方案2】:

实际上,这应该更快。而且它更具可读性。 ;-)

$s = preg_replace('/[^.0-9]/', '', '123.123a.123');
if (1 < substr_count($s, '.')) {
    $a = explode('.', $s);
    $s = array_shift($a) . '.' . implode('', $a);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2014-06-01
    • 2016-10-20
    相关资源
    最近更新 更多