【问题标题】:regex allows one character (it should not) why?正则表达式允许一个字符(它不应该)为什么?
【发布时间】:2013-09-05 22:20:43
【问题描述】:

您好,我正在尝试创建一个正则表达式来识别输入的金钱和数字。我必须允许数字,因为我希望以编程方式输入非格式化数字,然后我将自己格式化它们。出于某种原因,我的正则表达式允许一个字母字符作为可能的输入。

[\$]?[0-9,]*\.[0-9][0-9]

我了解我的正则表达式接受添加多个逗号并且还需要小数点后两位数的情况。我已经知道如何解决这个问题了。我已将其范围缩小到可能是*\. 作为问题

编辑

我找到了有效的正则表达式 [\$]?([0-9,])*[\.][0-9]{2},但我仍然不知道它最初是如何或为什么失败的

我正在使用.formatCurrency() 将输入格式化为货币格式。可以找到here,但它仍然允许我使用字母字符,所以我必须使用$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" }); 进一步屏蔽它,其中找到输入掩码here$(this) 是对文本类型输入元素的引用.我的代码看起来像这样

<input type="text" id="123" data-Money="true">

 //in the script
 .find("input").each(function () {          
        if ($(this).attr("data-Money") == "true") {                            
            $(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });
            $(this).on("blur", function () {
                $(this).formatCurrency();
            });

我希望这会有所帮助。我尝试创建一个 JSfiddle 但我知道如何添加外部库/插件/扩展

【问题讨论】:

  • 你错了,或者缺少上下文。
  • \. 中的反斜杠可能会被您使用的任何软件“吃掉”。您需要提供环境、失败代码等的详细信息。
  • 你用的是什么工具或语言,你说的是不可能的,除非你使用的工具有话要说:)
  • 正则表达式不尊重用户的语言环境。例如,输入字符串 €4.655,00 在欧洲部分地区是有效的货币值 - 这就是为什么如果您的语言支持,最好使用语言环境支持。我们需要有关您的环境的更多详细信息;这是 Linux shell、python、...?
  • 点和美元符号不会在您的正则表达式中转义。您应该将regex: "[\$]?([0-9,])*[\.][0-9]{2}" } 重写为regex: "[\\$]?([0-9,])*[\\.][0-9]{2}" }

标签: javascript jquery regex jquery-inputmask


【解决方案1】:

您在示例脚本中使用的“正则表达式”不是 RegExp:

$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });

相反,它是一个包含模式的字符串,在某些时候正在由您的库使用类似于

的方式将其转换为真正的正则表达式
var RE=!(value instanceof RegExp) ? new RegExp(value) : value;

在字符串中,反斜杠\ 用于表示特殊字符,如\n 表示换行符。在句号的开头添加反斜杠,即\.,没有任何作用,因为不需要“转义”句号。

因此,从您的 String 创建的 RegExp 根本看不到反斜杠。

不要提供字符串作为正则表达式,而是使用 JavaScript 的文字正则表达式分隔符。

所以而不是:

$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });

使用

$(this).inputmask('Regex', { regex: /[\$]?([0-9,])*[\.][0-9]{2}/ });

而且我相信您的“正则表达式”会按您的预期执行。

(注意使用正斜杠/ 来分隔你的模式,JavaScript 将使用它来提供真正的正则表达式。)

【讨论】:

  • 您是否通过阅读源代码了解var RE=!(value instanceof RegExp) ? new RegExp(value) : value;?为什么我不能标记你?
  • 不,不过如果你愿意,我可以。我很有信心我是对的,即使我假设就是这种情况,因为您提供的值是一个字符串。
  • 哦不,没关系。我只是想弄清楚这是常识,还是 jquery.inputmask 特有的东西
【解决方案2】:

首先,您可以将 '[0-9]' 替换为 '\d'。所以我们可以更干净地重写你的第一个正则表达式

\$?[\d,]*\.\d\d

分解:

\$?       - A literal dollar sign, zero or one
[\d,]*    - Either a digit or a comma, zero or more
\.        - A literal dot, required
\d        - A digit, required
\d        - A digit, required

由此可知,最小合法字符串为\.\d\d,三个字符长。您提供的正则表达式将从不针对任何一个字符串进行验证。

看看你的第二个正则表达式,

[\$]?     - A literal dollar sign, zero or one
([0-9,])* - Either a digit or a comma, subexpression for later use, zero or more
[\.]      - A literal dot, required
[0-9]{2}  - A digit, twice required

这具有与上面完全相同的最小可匹配字符串 - \.\d\d

编辑:如上所述,根据语言,您可能需要对正斜杠进行转义,以确保在处理字符串时不会被语言误解。

另外,顺便说一句,下面的正则表达式可能更接近您的需要。

[A-Z]{3} ?(\d{0,3}(?:([,. ])\d{3}(?:\2\d{3})*)?)(?!\2)[,.](\d\d)\b

解释:

[A-Z]{3}       - Three letters; for an ISO currency code
 ?             - A space, zero or more; for readability
(              - Capture block; to catch the integer currency amount
  \d{0,3}        - A digit, between one and three; for the first digit block
  (?:            - Non capturing block (NC)
    ([,. ])        - A comma, dot or space; as a thousands delimiter
    \d{3}          - A digit, three; the first possible whole thousands
    (?:            - Non capturing block (NC) 
      \2             - Match 2; the captured thousands delimiter above
      \d{3}          - A digits, three
    )*             - The above group, zero or more, i.e. as many thousands as we want
  )?              - The above (NC) group, zero or one, ie. all whole thousands
)              - The above group, i.e everything before the decimal
[.,]           - A comma or dot, as a decimal delimiter
(\d{2})        - Capture, A digit, two; ie. the decimal portion
\b             - A word boundry; to ensure that we don't catch another
                 digit in the wrong place.

John Kugelman 在this question 中的回答提供了否定前瞻。

这正确匹配(方括号中的匹配项):

[AUD 1.00]
[USD 1,300,000.00]
[YEN 200 000.00]
I need [USD 1,000,000.00], all in non-sequential bills.

但不是:

GBP 1.000
YEN 200,000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多