2

我有一个这样的字符串:

$string = "Half Board, 10% Off & 100 Euro Star - Save £535";

百分比可以是字符串中的任何位置。

这就是我所拥有的,但我不喜欢它有一个 preg_replace 和一个循环操作,这很重。我想要一个可以在一次操作中完成的正则表达式。

$string = "Half Board, 10% Off & 100 Euro Star - Save £535";
$string_array = explode(" ", $string);
$pattern = '/[^0-9,.]*/'; // non-digits

foreach($string_array as $pc) {

    if(stristr($pc, '%')) {

        $percent = preg_replace($pattern, '', $pc);
        break;
    }
}

echo $percent;
exit;
4

4 回答 4

4

更新:
从您添加到问题的代码中,我得到您的百分比可能看起来像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)

前瞻是这样工作的

  • \s*: 匹配零个或多个空格字符
  • %:百分号

因此,两者都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]

但这只是大量的工作,使用前瞻更容易。

于 2013-08-14T10:44:59.077 回答
1
$str = "Half Board, 10% Off & 100 Euro Star - Save £535";
preg_match("|\d+|", $str, $arr);
print_r($arr);
于 2013-08-14T10:35:27.190 回答
0

试试split喜欢

$str_arr = split(' ',$str);
$my_str = split('%',$str_arr[1]);
echo $my_str[0];
于 2013-08-14T10:36:33.243 回答
0

这应该有效:

$str = "Save 20% on iPhone chargers...";
if (preg_match_all('/\d+(?=%)/', $str, $match))
   print_r($match[0]);

现场演示:http: //ideone.com/FLKtE9

于 2013-08-14T10:45:23.283 回答