Как искать в строке значения и конвертировать значения - PullRequest
2 голосов
/ 30 мая 2019

У меня есть API, который принимает строку, которая должна быть правильно отформатирована перед входом на сервер.

Формат для входа на сервер следующий

"{Country ABR} {Day/Hour} {State ABR} {Title} {hrs.} ({Month Year}.)"

Несколько возможностей, которые клиент может отправить:

"US Construction 7/70 hrs."

"IA Private hrs US.

"OIL US 8/70 hrs (Dec 2014).

Несколько действительных примеров после преобразования пользовательского ввода:

"US 7/70 MI Construction hrs."

"US IA Private hrs."

"US OIL 8/70 hrs. (Dec 2014)" 

преобразователь упорядочивает ввод в правильном порядке. hrs всегда заканчивается точкой и переставляет ({Month Year}) вне предложения, как показано.

пока у меня есть

       [TestMethod]
    public void TestMethod1()
    {
        var toConvert = "USA Construction 70/700 (Dec 2014) hrs";
        var converted = ConvertHOSRules(toConvert);

        Assert.AreEqual(converted, "USA 70/700 Construction hrs.(Dec 2014)");
    }

    private string ConvertHOSRules(string input)
    {
        //todo refactor
        string output = "";

        string country = Regex.Match(input, @"\b(USA|CAN|MEX)\b").Value +" ";
        string dateHours =  Regex.Match(input,@"\d{1,2}\/\d{1,3}").Value + " ";
        string hrs = Regex.Match(input, @"\b(hrs)\b").Value ;
        var date = Regex.Match(input, @"\(([a-zA-Z]+\s{1}[0-9]{4})\)").Value + " ";
        string title = input.Replace(country, "").Replace(date, "").Replace(dateHours, "").Replace(hrs, "");
        output = $"{country} {dateHours} {title} {hrs}.{date}";
        return output;

    }

Это проходит, мне нужно провести рефакторинг ... + "" как ленивый программист, как нулевая охрана

1 Ответ

2 голосов
/ 30 мая 2019

Этот вопрос довольно интересный, особенно если мы хотим разработать алгоритмы для него, потому что я предполагаю, что наши регулярные выражения были бы довольно ненужными.


Если мы хотим сделать это с помощью выражений, я бы начал с простого выражения, такого как перечисление возможных стран и государств в двух группах захвата:

(US|UK|FR)
(CA|WA|IA|MO|MI)

тогда наши часы хорошо структурированы:

(\d+\/\d+)

также как месяц (.+?) и год ([0-9]+):

\(((.+?)\s+([0-9]+))\)

и здесь мы столкнемся с проблемой с другими ключевыми словами, такими как Construction и OIL, мы могли бы добавить мин 3 символа, чтобы не конфликтовать с государствами и странами:

([A-Z][a-z]{2,}|[A-Z]{3,})

и, наконец, мы очистим нашу строку, собрав все оставшиеся пробелы и другие символы, такие как hrs., который просто повторяется, и мы можем не захотеть сопоставлять или фиксировать это.

(.*?)

Наконец, мы бы объединились, используя чередование:

(US|UK|FR)|(CA|NY|IA|TX|MI)|(\d+\/\d+)|\(((.+?)\s+([0-9]+))\)|([A-Z][a-z]{2,}|[A-Z]{3,})|(.*?)

DEMO

Тест

using System;
using System.Text.RegularExpressions;

public class Example
{
    public static void Main()
    {
        string pattern = @"(US|UK|FR)|(CA|NY|IA|TX|MI)|(\d+\/\d+)|\(((.+?)\s+([0-9]+))\)|([A-Z][a-z]{2,}|[A-Z]{3,})|(.*?)";
        string input = @"US 7/70 MI Construction hrs.
US IA Private hrs.
US OIL 8/70 hrs. (Dec 2014)
UK 7/70 MI Construction hrs.
UK IA Private hrs.
UK OIL 8/70 hrs. (Dec 2014)
FR 7/70 MI Construction hrs.
FR IA Private hrs.
FR OIL 8/70 hrs. (Dec 2014)";
        RegexOptions options = RegexOptions.Multiline;

        foreach (Match m in Regex.Matches(input, pattern, options))
        {
            Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
        }
    }
}

enter image description here

DEMO

RegEx

Если это выражение нежелательно, его можно изменить / изменить в regex101.com .

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

...