从字符串中提取一个单独的(无符号)整数

396

我想从包含数字和字母的字符串中提取数字:

"In My Cart : 11 items"

我想提取数字 11

23个回答

635

如果你只想筛选出数字以外的所有内容,最简单的方法是使用 filter_var 函数:

$str = 'In My Cart : 11 items';
$int = (int) filter_var($str, FILTER_SANITIZE_NUMBER_INT);

66
数字前面的破折号会被视为减号。 - Elnur Abdurrakhimov
50
不仅仅是数字前面,任何正负号都不会被截断。如果你有 xxx-yyy-24,你会得到 --24。你可以使用 str_replace(array('+','-'), '', $result) 删除两个符号。 - imclickingmaniac
4
你可以使用 max(0,filter_var($str, FILTER_SANITIZE_NUMBER_INT)) 来替代使用数组和字符串替换。这个方法可以使代码更简洁易懂,并且保持原有功能。 - Eduard
2
使用max()函数在字符串中也会返回负号,希望可以使用strreplace()函数来解决。感谢提供的建议。 - Shiva Avula
30
abs((int) filter_var($str, FILTER_SANITIZE_NUMBER_INT)); - MECU
显示剩余5条评论

406
$str = 'In My Cart : 11 12 items';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);

2
我该如何将我的数字存储在一个简单的变量中而不是数组中? - Bizboss
38
$var = implode(' ', $matches[0]); - Gaurav
3
同样的思路,尝试使用 $newstr = preg_replace('!\d+!', '', $str);。它将从字符串中删除所有数字。例如:$str = 'In My Cart : 11 12 items'; 将输出 In My Cart : items - Aether
87
这不是一种资源友好的方法。请使用preg_replace("/[^0-9]/","",$string);filter_var($str, FILTER_SANITIZE_NUMBER_INT); - eapo
8
filter_var($str, FILTER_SANITIZE_NUMBER_INT); 提取了数字、加号减号。而正则表达式只提取了数字! - PATROMO
显示剩余5条评论

378
preg_replace('/[^0-9]/', '', $string);

这应该做得更好!...


13
我喜欢这个函数,因为它返回一个字符串,不像 preg_match_all 的例子返回一个数组。我也喜欢它,因为我只需要数字,而不是像 filter_var 的例子那样带加号或破折号。 - Darrell Duane
48
这种方法需要小心:类似于“在我的车里_价格:500.00”会打印出50000 - ErickBest
25
考虑到问题是“从字符串中提取数字”,所以小数点不是一个数字,@ErickBest说得对,这是件好事! - rybo111
1
稍微简单一点:preg_replace('/\D/', '', $string); - Nicholas Ruunu
2
使用preg_replace('/[^0-9.]/','',$string)代替,如果您想保留数字中的. - shamaseen
唯一有效的一个。 - Karra Max

103

使用preg_replace函数:

$str = '(111) 111-1111';
$str = preg_replace('/\D/', '', $str);
echo $str;

输出:1111111111


4
非常好,它可以将“+387 (61) 634-783”字符串直接转换为“38761634783”。您无需像Gaurav的答案那样处理数组。 - kuzey beytar
1
绝对是最佳答案。http://sandbox.onlinephpfunctions.com/code/9d00d3e3e3c818267577fa9ae4531cc0ee38bb1a - Steffan
我建议使用 + 量词来匹配更长的字符串 / 较少的替换。 - mickmackusa
这个回答似乎在回答一个不同的问题。OP只是从字符串中分离出一个整数值——购物车中的物品数量。这个页面的理解范围似乎已经远远超出了OP实际提出的问题。这是对另一个问题的正确答案。 - mickmackusa

24

对于浮点数,

preg_match_all('!\d+\.?\d+!', $string ,$match);

感谢您指出错误。@mickmackusa


这实际上是错误的 :) 应该是'!\d*.?\d+!' - Yash
我更喜欢使用“?”作为字面点的量词。我不希望浮点值包含多个小数点符号。Yash的注释模式具有讽刺意味的是错误的。点需要在前面加上斜杠才能使其成为字面量。 - mickmackusa
1
OP的示例文本表明浮点值没有潜在的可能性——购物车中有部分商品是没有意义的。示例文本中也只有一个整数值,因此使用preg_match_all()是过度的。这最多是对不同问题的正确答案。 - mickmackusa
@mickmackusa 你说得完全正确!我之前看这个问题是因为另一个用例,然后有了一个关于如何实现它的想法。当时提交的答案可能就是我用的解决方案。 - Yash

12

这并没有验证字符串中三个整数集之间的逗号。...复制粘贴别人的模式而不理解/测试它的问题。 - mickmackusa
当用户将其他Stack Overflow答案复制粘贴到页面上时,Stack Overflow并不会受益。如果另一个Stack Overflow页面包含了解决此页面的建议,则正确的行为是使用超链接作为关闭此页面的重复项的原因。最终,这个答案并不适合OP的问题。OP不可能隔离浮点值,我们也不知道是否有千位分隔符。 - mickmackusa

11
你可以使用preg_match
$s = "In My Cart : 11 items";
preg_match("|\d+|", $s, $m);
var_dump($m);

echo '<p>'.$m[0].'</p>'; - Pathros

10

使用preg_replace

$str = 'In My Cart : 11 12 items';
$str = preg_replace('/\D/', '', $str);
echo $str;

我建议使用 + 量词来匹配更长的字符串 / 较少的替换。 - mickmackusa
为什么OP想要形成字符串值1112?可能会从中获得什么好处? - mickmackusa

10
以下是针对以下示例输入字符串的资源友好解决方案:
$string = "In My Cart : 11 items";

最快的方法:filter_var — 使用指定的过滤器过滤变量
var_dump(
    filter_var($string, FILTER_SANITIZE_NUMBER_INT)
); // string(2) "11"

几乎最快的方法:str_replace — 将所有出现的搜索字符串替换为替换字符串
var_dump(
    str_replace(array('In My Cart : ',' item', 's'),"", $string)
); // string(2) "11"

足够快的方法:preg_replace — 执行正则表达式搜索和替换
var_dump(
    preg_replace("/[^0-9]/","",$string)
); // string(2) "11"

然而,str_replace 的简单性导致了速度的提升,但仅适用于有限的用例。 preg_replacestr_replacefilter_var 更加灵活多样。
可以使用一个函数来指定要替换的内容,而不是使用preg_replace_callback
使用preg_replace_callback可以在一次调用中进行多个替换。 filter_var清理选项方面有限制。

filter_var($key, FILTER_SANITIZE_NUMBER_INT) 可以解决 invoice_no[0] 转换为 0 的问题。 - Mohamed Raza

7
$value = '25%';

或者

$value = '25.025$';

或者

$value = 'I am numeric 25';
$onlyNumeric = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

这将仅返回数字值


为什么OP可能想要容纳浮点值?OP的用户如何在购物车中拥有部分商品?这似乎是对不同问题的正确答案。 - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接