如何匹配来自Firefox浏览器的Regex时期?

Zac*_*ott 1 c# regex firefox

我有以下C#代码,它们应匹配数量/ $ price字符串,如"4/$ 3.99".它整天都在工作,直到我们对Firefox浏览器返回的字符串使用它.77.77变为77(降低.77美分).

var matches = Regex.Match(_priceText, 
    @"^\s?((?<qty>\d+)\s?/)?\s?[$]?\s?(?<price>[0-9]?\.?[0-9]?[0-9]?)");

if( matches.Success)
{
    if (!Decimal.TryParse(matches.Groups["price"].Value, out this._price))
        this._price = 0.0m;
    if (!Int32.TryParse(matches.Groups["qty"].Value, out this._qty))
        this._qty = (this._price > 0 ? 1 : 0);
    else
        if (this._price > 0 && this._qty == 0)
            this._qty = 1;
}
Run Code Online (Sandbox Code Playgroud)

知道为什么这段时间不会来自Firefox字符串,但C#字符串匹配?我们使用的Firefox没有任何特殊之处.这是Firefox网站上简单的简1252代码页下载.计算机的本地设置是不变的北美等.我们有两台不同的计算机显示相同的效果.它是Firefox 3.6.4,没什么花哨或测试版.

Ahm*_*eed 5

Firefox不是问题.模式不完整.

请尝试使用此模式:

@"^\s?((?<qty>\d+)\s?/)?\s?[$]?\s?(?<price>[0-9]{1,2}\.?[0-9]?[0-9]?)"
Run Code Online (Sandbox Code Playgroud)

原始模式中的问题是(?<price>[0-9]?\.?[0-9]?[0-9]?)部分.您描述的问题出现在以2位数字开头的任何数字上,而不仅仅是Firefox值.您的样本是4/$3.994/$33.99会引起同样的问题.该[0-9]?\.?[0-9]?[0-9]?部分匹配一个数字后跟一个句点.不幸的是,?在几乎所有事情之后,模式中都散布着可选的元字符,这就是为什么这个bug出现了.因为77.77它匹配前7,那么它应匹配一个点但等待,有一个第二个7没有点(这是可选的\.?)所以它很乐意跳过它.接下来,模式需要2个可选数字,但它会看到一个点并停止,因此只返回77.这是一般的想法.

话虽如此,您应该在构建模式时精确地列出哪些输入有效.您的原始模式表明该price组完全是可选的.仔细看看; 一切都?附加了它.那么你的目标是什么?它是可选的吗?是否允许整数?它必须是数字中带小数的小数.xy吗?我在顶部建议的模式用于[0-9]{1,2}强制存在1-2个数字,同时保留.xy部分可选.

如果该.xy部分是真正可选的,您可以将您的price组更新为:(?<price>\d{1,2}(?:\.\d{1,2})?)- 这样,可选的?元字符适用于可选的所有内容,并且仅指定一次.这使得IMO模式更具可读性.该(?:...)部分是可选的(具体使用?:不是实际的分组),但最好避免不必要地捕获该组.有了这些变化,新模式将是:

@"^\s?((?<qty>\d+)\s?/)?\s?[$]?\s?(?<price>\d{1,2}(?:\.\d{1,2})?)"
Run Code Online (Sandbox Code Playgroud)

请注意,该模式仍然存在问题,具体取决于您的要求.整个qty组是可选的,这意味着4/可以从输入中省略该部分,并且输入$3.99将是有效的.如果这是必需的,那么不要使它成为可选:

@"^\s?((?<qty>\d+)\s?/)\s?[$]?\s?(?<price>\d{1,2}(?:\.\d{1,2})?)"
Run Code Online (Sandbox Code Playgroud)