1

我有一个 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;

    }

这是通过我需要重构.. +“”就像懒惰程序员的空守卫

4

1 回答 1

2

这个问题很有趣,特别是如果我们想为它设计算法,因为我猜我们的正则表达式是不必要的。


如果我们希望使用表达式来做到这一点,我将从一个简单的表达式开始,例如在两个捕获组中列出可能的国家和州:

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

那么我们的时间安排得很好:

(\d+\/\d+)

月份(.+?)和年份也是如此([0-9]+)

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

在这里,我们将面临其他关键字的问题,例如Constructionand 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,})|(.*?)

演示

测试

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);
        }
    }
}

在此处输入图像描述

演示

正则表达式

如果不需要此表达式,可以在regex101.com中对其进行修改/更改。

正则表达式电路

jex.im可视化正则表达式:

在此处输入图像描述

于 2019-05-30T15:55:43.203 回答