更新:
从您添加到问题的代码中,我得到您的百分比可能看起来像12.3%
甚至.50%
. 在这种情况下,您正在寻找的正则表达式是这样的:
if (preg_match_all('/(\d+|\d+[.,]\d{1,2})(?=\s*%)/','some .50% and 5% text with 12.5% random percentages and 123 digits',$matches))
{
print_r($matches);
}
返回:
Array
(
[0] => Array
(
[0] => .50
[1] => 5
[2] => 12.5
)
[1] => Array
(
[0] => .50
[1] => 5
[2] => 12.5
)
)
表达式解释:
(\d+|\d*[.,]\d{1,2})
: 是 OR -> 匹配数字\d+
,或者\d*
零个或多个数字,后跟小数分隔符 ( [.,]
) 和 1 或 2 位数字 ( \d{1,2}
)
(?=\s*%)
: 仅当上述组后跟零个或多个空格和一个 % 符号
使用正则表达式,通过积极的前瞻,你可以得到你想要的:
if (preg_match_all('/\d+(?=%)/', 'Save 20% if you buy 5 iPhone charches (excluding 9% tax)', $matches))
{
print_r($matches[0]);
}
给你:
array (
0 => '20',
1 => '9'
)
我相信这就是您要寻找
的正则表达式的工作方式如下:
\d+
匹配至少 1 个数字(尽可能多)
(?=%)
: 前提是后面有一个%
符号
由于前瞻,在5
我给出的示例中不匹配,因为它后面是空格,而不是%
符号。
如果您的字符串可能格式错误(数字和%
符号之间有任意数量的空格),前瞻也可以处理。正如 ridgerunner 向我指出的那样,只有lookbehinds 需要是固定大小的,所以:
preg_match_all('/\d+(?=\s*%)/', $txt, $matches)
前瞻是这样工作的
因此,两者都123 %
符合123%
模式,并且将匹配。
阅读正则表达式的好地方是regular-expressions.info
如果“复杂”正则表达式(即带有环视断言)不是您的一杯茶(尽管我强烈建议学习使用它们),您可以诉诸拆分字符串:
$parts = array_map('trim', explode('%', $string));
$percentages = array();
foreach($parts as $part)
{
if (preg_match('/\d+$/', $part, $match))
{//if is required, because the last element of $parts might not end with a number
$percentages[] = $match[0];
}
}
在这里,我只是使用%
as 分隔符来创建一个数组,并修剪每个字符串部分(以避免尾随空格),然后继续检查每个子字符串,并匹配该子字符串末尾的任何数字:
'get 15% discount'
['get 15', 'discount']
/\d+$/, 'get 15' = [15]
但这只是大量的工作,使用前瞻更容易。