如何在字符串中搜索值并转换值

时间:2019-05-30 14:17:50

标签: c# regex algorithm regex-group regex-alternation

我有一个API,该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)" 

转换器将输入按正确的顺序排列。小时始终以句点结尾,并在句子外重新排列({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 个答案:

答案 0 :(得分:2)

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


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

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

然后我们的时间结构合理:

(\d+\/\d+)

(.+?)年和([0-9]+)年也是:

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

在这里,我们将面临诸如ConstructionOIL之类的其他关键字的问题,我们可以添加至少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电路

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

enter image description here