1

我有一个字符串:

Product, Q.ty: 1, Price: 120.00

我想选择第一个逗号之后的所有内容,直到最后两位小数 (.00) - 或者,换句话说,选择Product,尽管它是可变的;不可变的是, Q.t,众所周知,字符串中的最后两个字符将是两个数字,前面有一个点.- 但是只有最后一个总是0,前面的一个可以是任何东西0-9,但总是一个数字。

我用它来匹配字符串:

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

问题是,当最后两位数字不是 00 而是 50、40、30 等其他数字时,它会失败。如果我对单个数字“0”使用相同的正则表达式,它也不会工作,因为它会捕获字符串中的第一个 0 就像我之前的示例一样,并将省略剩余的 0。

如何调整此表达式以捕获前面有“。”的一组数字 点?

*进一步说明:此 preg_replace 在 foreach 循环内;有些数据与我试图传递的模式完全不匹配;没关系,所以在这些情况下,我可以按原样打印字符串;但是对于 foreach 中存在匹配项的情况,我想用任何内容替换部分字符串*

谢谢

4

5 回答 5

2

为什么不只是

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

它将捕获任何带有小数位的尾随“数字”?

于 2013-07-24T14:46:36.207 回答
2
 /([^,]*), Q\.ty: (\d*), Price: (\d*\.\d{2})/

通过使用([^,]*),它将使用字符串中的逗号作为第一个分隔符。这将捕获字符串的开头直到第一个逗号,第二个匹配将是数量,最后一个匹配将是价格。

所以你提供的字符串:

 Product, Q.ty: 1, Price: 120.00

将返回

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

在旁注中,我不知道 Q.ty 中 Q 之后的这段时间是否在您的示例中是故意的,或者只是一个错字。

于 2013-07-24T15:12:52.413 回答
2

你可以试试

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

这应该捕获从第一个逗号到最后两位十进制数字的所有内容到 $2 中,产品标签保留在 $1 中

于 2013-07-24T15:22:33.733 回答
2

我想有人(总是有)会说“你可以用str_replace()and得到碎片explode()。” 然而它并没有更快。

<?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);

?>

输出

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
)

使用更字面的方法,只要$string不偏离,就不会提高 preg_match 函数的性能。

$pattern = "!^(Product), (Q\.ty): ([0-9]+), (Price): ([0-9.]+)$!";
于 2013-07-24T15:35:41.830 回答
1

如果你想要一个文字点,你应该把它转义:\。

于 2013-07-24T14:48:28.283 回答