PHP正则表达式匹配有效工资,包括符号

PHP正则表达式匹配有效工资,包括符号,php,regex,Php,Regex,我试图验证输入是否与薪资或薪资范围匹配-问题是用户可以输入许多可能的值 例如,以下内容有效: 2000 2,000 2000.00 2,000.00 2000 - 4000 2,000-4,000 2,000.00-4,000.00 $2,000.00-$4,000.00 £2,000.00-£4,000.00 最初,我们开始允许除字母以外的所有内容,但这将允许类似2!000,这将是无效的 目前我们已经得到: if (preg_match('/^\d|\d,\d+(\.(\d{2}))?$/

我试图验证输入是否与薪资或薪资范围匹配-问题是用户可以输入许多可能的值

例如,以下内容有效:

2000
2,000
2000.00
2,000.00

2000 - 4000
2,000-4,000
2,000.00-4,000.00
$2,000.00-$4,000.00
£2,000.00-£4,000.00
最初,我们开始允许除字母以外的所有内容,但这将允许类似2!000,这将是无效的

目前我们已经得到:

if (preg_match('/^\d|\d,\d+(\.(\d{2}))?$/', $i)) {
   return true;
}

这对前4个示例有效,但它允许2a000之类的无效内容-是否有方法列出字符串不能包含的所有内容(例如,除了货币、句点和逗号以外的字母和符号)但是仍然要进行模式匹配,以便我们可以验证数字。例如,您可以在组中捕获
$
,然后为了一致性,使用反向引用来匹配第二部分中的相同符号(这是可选的)

要稍微缩短模式,可以使用
(?2)
重复匹配捕获组2中的数字

^([$£]?)((?:\d{1,3}(?:,\d{3})*|\d+)\b(?:\.\d{2})?)(?:\h*-\h*\1(?2))?$
部分地

  • ^
    字符串的开头
  • Capturegroup 1
    • [$英镑]?
      可选择匹配
      $
  • 关闭组
  • 捕获第2组
    • (?:\d{1,3}(?:,\d{3})*
      匹配1-3位数字并重复0多次匹配
      和3位数字
    • |
    • \d+
      匹配1+个数字
    • \b
      单词边界
    • (?:\。\d{2})?
      可以选择匹配一个点和两个数字
  • 关闭组
  • (?:
    非捕获组
    • \h*-\h*\1
      在0+水平空白字符之间匹配
      -
      ,然后反向引用组1中捕获的内容(可选
      $
    • (?2)
      重复第2组中的模式以匹配数字
  • )?
    关闭组并将其设置为可选
  • $
    字符串结尾

这一条非常严格,所以第二组的所有条目都通过,第一组的条目都不通过

^[$£]?\d,?000(\.00)?([ -]+[$£]?\d,?000(\.00)?)?$
你也可以做一些更为仁慈的事情,比如用
\D
替换
[$£]
以允许使用任意货币等等


如果您得到一个连字符-,则表示您有范围。为了简单起见,我将在连字符上分解()并使用 $numberFormatter=新的numberFormatter('en_US',numberFormatter::CURRENCY); var_dump($numberFormatter->formatCurrency(1234.56789,“USD”)

如果格式化程序能够返回字符串,则表示输入有效


即使提交的是薪水而不是范围,这也会起作用。

我会去掉所有不是数字、点或破折号的内容,然后验证剩余的内容。我同意Alex的观点,你应该规定用户只能输入数字或用一个连字符分隔的数字,没有空格。(这类东西有“滑块”)若要获取他们的首选货币,请添加另一个输入/选择字段。否则,您将需要模糊的薪资期望或艰巨的解析。通过请求原始est/基本部分中的数据,您可以简单地以一致的格式和您选择的样式存储和输出数据。问题显示exa两种货币的示例。我假设它可能需要任何货币的输入。某些货币有不同的分隔符,因此只接受数字是无效的。这不起作用。例如,它不会匹配$2000。哦,它应该匹配示例中的两个列表吗?非常简单的修改(请参见编辑).后面引用的用法非常贴切。这是最好的答案。