用于查找美元金额但不匹配 IP 地址的正则表达式



我的文本部分可能包含美元金额(可能以美元符号为前缀,也可能不包含美元符号)和IP地址。我需要一个正则表达式来识别美元金额,但不匹配 IP 地址的部分。

例如,如果文本是:

12.34 56.78.90.12 34.56

我的开始尝试是:

([1-9]d*.d{2})

这是我想要匹配的,但它匹配部分 IP 地址。然后我尝试:

[^.]([1-9]d*.d{2})[^.]

但这种情况在几乎所有情况下都更糟。

正则表达式需要匹配"12.34"

和"34.56",但不能匹配"56.78"或"90.12"。任何帮助将不胜感激。

另一种与 REGEX 不同的方法是假设每个元素之间有一个空格(dollar amount or ip address)是按空格分解元素并获取只有一个点的元素列表。

$text = "12.34 56.78.90.12 34.56";
$dollars_amt = array_filter(explode(' ', $text), function($s) {
    if (substr_count($s, '.') == 1) {
        return $s;
    }
});
print_r($dollars_amt);

结果:

Array ( [0] => 12.34 [2] => 34.56 )

使用环顾断言和单词边界锚点来确保匹配项周围没有点:

(?<!.)b[1-9]d*.d{2}b(?!.)

在 regex101.com 上实时测试。

(?<=^|[^d.])d+.d+(?=[^d.]|$)

它基本上试图匹配这个:

d+.d+

当字符串的开头(^)或不是数字或点([^d.])的东西在它后面,字符串的结尾($)或不是数字或点的东西([^d.])在它后面。

在这里试试。

使用不合格的(*SKIP)(*FAIL)模式的执行速度将是当前发布的其他正则表达式模式的两倍多。

/d{1,3}.d{1,3}.d{1,3}.d{1,3}(*SKIP)(*FAIL)|$?[1-9]d*.d{2}/
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- IP address   ^^^^^^^^^^^^^^^- currency amount

这将首先查找并取消 IP 地址的资格,然后再尝试将您的货币值与可选的前导美元符号匹配。 此模式允许您在不使用捕获组的情况下匹配您的美元金额 -- 这将提高性能并减少输出阵列膨胀preg_match_all()

模式演示链接

代码:(PHP演示)

$string='12.34 56.78.90.12 34.56 156.8.90.2 $99999.99';
var_export(preg_match_all('/d{1,3}.d{1,3}.d{1,3}.d{1,3}(*SKIP)(*FAIL)|$?[1-9]d*.d{2}/',$string,$out)?$out[0]:'fail');

输出:

array (
  0 => '12.34',
  1 => '34.56',
  2 => '$99999.99',
)

最新更新