Как сопоставить период в Regex из браузера Firefox? - PullRequest
1 голос
/ 09 июня 2010

У меня есть следующий код C #, который должен соответствовать строке количества / $, например, "4 / $ 3.99".Он работает весь день, пока мы не используем его против строки, возвращенной из браузера Firefox.77.77 становится 77 (отбрасывая 0,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;
}

Есть идеи, почему период не совпадает, исходя из строки Firefox, но строка C # совпадает?Там нет ничего особенного в Firefox, который мы использовали.Это простая кодовая страница Jane 1252, загруженная прямо с сайта Firefox.Локальные настройки компьютера не изменяются в Северной Америке и т. Д. У нас есть два разных компьютера, демонстрирующие одинаковые эффекты.Это Firefox 3.6.4, ничего особенного или бета.

1 Ответ

5 голосов
/ 09 июня 2010

Firefox не проблема. Шаблон неполный.

Попробуйте этот шаблон вместо:

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

Проблема в исходном шаблоне - это часть (?<price>[0-9]?\.?[0-9]?[0-9]?). Описанная вами проблема возникает с любым числом, начинающимся с 2 цифр, а не только со значениями Firefox. Ваш образец был 4/$3.99, но 4/$33.99 вызвал бы ту же проблему. Часть [0-9]?\.?[0-9]?[0-9]? соответствует цифре, за которой следует точка. К сожалению, шаблон почти полностью заполнен необязательными метасимволами ?, и поэтому эта ошибка появилась. Для 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})?)"

Обратите внимание, что шаблон все еще имеет проблемы, в зависимости от ваших требований. Вся группа qty является необязательной, то есть часть 4/ может быть исключена из ввода, а ввод $3.99 будет действительным. Если это необходимо, не делайте это необязательным:

@"^\s?((?<qty>\d+)\s?/)\s?[$]?\s?(?<price>\d{1,2}(?:\.\d{1,2})?)"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...