Професионална програма
Loading...
+ Нов въпрос
Elena123456 avatar Elena123456 90 Точки

03. SoftUni Bar Income (40/100) - Regular Expressions - Exercise

Can somebody please tell me where is the problem in this exercise with RegEx?

 

https://softuni.bg/trainings/resources/officedocument/49595/regular-expressions-exercise-csharp-fundamentals-may-2020/2830

https://judge.softuni.bg/Contests/Compete/Index/1668#2

 

using System;
using System.Text.RegularExpressions;

namespace text
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var regex = new Regex(@"^%(?<name>[A-Z][a-z]+)%[^|$%.]*<(?<product>\w+)>[^|$%.]*\|(?<quantity>[0-9]{1,})\|[^|$%.]*?(?<price>[0-9]+[\.]?[0-9]?)\$$");
            double totalIncome = 0;
            string input = string.Empty;
            while ((input = Console.ReadLine()) != "end of shift")
            {

                if (regex.IsMatch(input))
                {
                    var matches = regex.Matches(input);
                    foreach (Match match in matches)
                    {
                        string quantity = match.Groups["quantity"].Value;
                        int quantityInt = int.Parse(quantity);
                        string price = match.Groups["price"].Value;
                        double priceDecimal = double.Parse(price);
                        double totalPrice = quantityInt * priceDecimal;
                        Console.WriteLine($"{match.Groups["name"]}: {match.Groups["product"]} - {totalPrice:F2}");
                        totalIncome += totalPrice;
                    }
                }
            }

            Console.WriteLine($"Total income: {totalIncome:F2}");
        }

    }

}

 

Тагове:
0
C# Fundamentals
MartinBG avatar MartinBG 3077 Точки
Best Answer

Грешката е в тази част от регекса:

(?<price>[0-9]+[\.]?[0-9]?)

Така написан, ще приеме за валидна цена стойност като:

1.

Защото не изискваме след десетичната точка да има цифра

Но няма да приеме:

1.22

Защото има повече от една цифра след десетичната точка.

Променете го на:

(?<price>[0-9]+(\.[0-9]+)?)

Или - по-добре, така:

(?<price>\d+(?:\.\d+)?)

 

2
Elena123456 avatar Elena123456 90 Точки

Здравейте и много благодаря за разясненията. :)

Разбирам,че благодарение на двете допълнителни скоби създаваме група и казваме, че ако числото има ".", то задължително трябва да има след нея едно или повече digit. Така изключваме комбинации 2. , 1. и т.н.  А с последната "?" казваме, че може да има числото "."  и digit след нея, но може и цялата тази група да липсва, т.е  числото може да е цяло.

Но не мога да разбера защо във втория пример е използвано "?:", което Кенов на лаба представи, като начин за изключване на дадена група. Нали тази група също ще ни трябва за стойността на  числото, ако изобщо съществува, защо е по-добре тогава да започва с "?:" ?

Извинявам се за въпроса, но едва от три дена уча RegEx и тъкмо навлизам в тях.

Поздрави! 

1
22/11/2020 11:36:29
Elena123456 avatar Elena123456 90 Точки

Разбрах го.

"?:" прави така, че числата след десетичната запетая да не се смятат за отделна група, а ако съществуват да се мачнат към вече съществуващата група "price".

Хубав неделен ден! :)

1