我有一个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;
}
这已经过去了,我需要重构。+“”就像是懒惰的程序员的空守护器
答案 0 :(得分:2)
这个问题非常有趣,特别是如果我们想为其设计算法时,因为我的猜测是我们的正则表达式是不必要的。
如果我们希望使用表达式来做到这一点,我将从一个简单的表达式开始,例如在两个捕获组中列出可能的国家和州:
(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,})|(.*?)
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可视化正则表达式: