简体   繁体   English

正则表达式以匹配带点号的数字

[英]Regular expression to match digits preceded by a dot

I have a string: 我有一个字符串:

Product, Q.ty: 1, Price: 120.00

I want to select everything after the first comma up to the last two decimal digits (.00) - or, in other words, select the Product , which will be variable though; 我想选择从第一个逗号到最后两个十进制数字(.00)的所有内容,或者换句话说,选择Product ,尽管它会是可变的; what is not variable is , Qt and it is also known that the last two characters in the string will be two digits preceded by a dot . 不是可变的是, Qt ,并且还知道字符串中的最后两个字符将是两个数字,并以一个小圆点开头. - However only the last one will be always 0 , the one preceding it could be anything 0-9 , but always a digit. -但是,只有最后一个将始终为0 ,其前一个可以为0-9 ,但始终为数字。

I've used this to match the string: 我用它来匹配字符串:

preg_replace('/' . preg_quote(', Q.t') . '.*?' . preg_quote('.00') . '/', '', $data );

the problem is that it fails when the last two digits are not 00 but something else like 50, 40, 30 etc. If I use the same regex with a single digit '0', it won't work either because it will catch the first 0 in a string like in my earlier example and will leave out the remaining 0. 问题是,当最后两位数字不是00而是其他诸如50、40、30等时,它将失败。如果我使用带有单个数字“ 0”的同一个正则表达式,则将不起作用,因为它将捕获像我之前的示例一样,字符串中的第一个0,将忽略其余的0。

How to adjust this expression to catch a group of digits preceded by a '.' 如何调整此表达式以捕获以“。”开头的一组数字 dot? 点?

*one further note: this preg_replace is inside a foreach loop; *另外一点:这个preg_replace在foreach循环中; some data won't match at all the pattern I'm trying to pass; 有些数据与我尝试传递的模式完全不匹配; which is ok, so in those cases I can print the strings the way they are; 没关系,因此在这种情况下,我可以按原样打印字符串; but for the cases in the foreach where there's a match, I want to replace part of the string with nothing* 但是对于foreach中存在匹配项的情况,我想将字符串的一部分替换为空*

Thank you 谢谢

Why not just 为什么不只是

/(\d+\.\d{2})$/

which would capture any trailing "numbers" with a decimal place? 哪个将捕获任何带小数位的尾随“数字”?

 /([^,]*), Q\.ty: (\d*), Price: (\d*\.\d{2})/

By using ([^,]*), it will use the comma in the string as the first delimiter. 通过使用([^,]*),它将使用字符串中的逗号作为第一个定界符。 This will capture the beginning of the string up to the first comma, the second match will be quantity and the last match will be the price. 这将捕获字符串的开头,直到第一个逗号,第二个匹配为数量,最后一个匹配为价格。

So your provided string: 因此,您提供的字符串:

 Product, Q.ty: 1, Price: 120.00

will return 将返回

$1 = Product
$2 = 1
$3 = 120.00

on a side note I don't know if that period after Q in Q.ty is intentional in your example or just a typo. 顺便说一句,我不知道Q.ty中Q之后的那个时期是故意的还是错别字。

You can try 你可以试试

(.+?), (Q\.ty: \d+, .+?\.\d{2})

This should capture everything from the first comma to the last two decimal digits into $2, with the product label being kept in $1 这应该将从第一个逗号到最后两个十进制数字的所有内容捕获到$ 2中,产品标签保持在$ 1中

I figured someone (there always is) would say "You can get the pieces with str_replace() and explode() ." 我以为有人(总是这样)会说:“您可以使用str_replace()explode() 。” However it's not faster. 但是,它并不快。

<?php

$string = "Product, Q.ty: 1, Price: 120.00";
$removals = array(",",":");


$stime = microtime();
    $nstring = str_replace($removals,'',$string);
    $parts = explode(" ",$nstring);

echo microtime()-$stime."secs\n";
    print_r($parts);

$pattern = "!^([A-Za-z]+),\s([A-Za-z.]+)\:\s([0-9]+),\s([A-Za-z]+):\s([0-9.]+)$!";

$ptime = microtime();
    $m = preg_match($pattern,$string,$matches);
echo microtime()-$ptime."secs\n";

print_r($matches);

?>

Output 输出量

4.0999999999958E-5secs
Array
(
    [0] => Product
    [1] => Q.ty
    [2] => 1
    [3] => Price
    [4] => 120.00
)
3.5000000000007E-5secs
Array
(
    [0] => Product, Q.ty: 1, Price: 120.00
    [1] => Product
    [2] => Q.ty
    [3] => 1
    [4] => Price
    [5] => 120.00
)

Using a more literal approach ,providing the $string doesn't deviate, does not improve performance of the preg_match function. 使用更文字的方法,提供$string不会偏离,不会提高preg_match函数的性能。

$pattern = "!^(Product), (Q\.ty): ([0-9]+), (Price): ([0-9.]+)$!";

如果需要文字点,则应对其进行换行:\\。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM