C# 如何在字符串中搜索值并转换值
我有一个API,它接受在进入服务器之前需要正确格式化的字符串 进入服务器的格式如下C# 如何在字符串中搜索值并转换值,c#,regex,algorithm,regex-group,regex-alternation,C#,Regex,Algorithm,Regex Group,Regex Alternation,我有一个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
"{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;
}
这是我需要重构的过程。。“+”就像是懒散程序员的空保护这个问题很有趣,特别是如果我们想为它设计算法,因为我猜我们的正则表达式是相当不必要的
如果我们希望通过表达式实现这一点,我将从一个简单的表达式开始,例如将可能的国家和州分为两组:
(US|UK|FR)
(CA|WA|IA|MO|MI)
那么我们的时间安排得很好:
(\d+\/\d+)
月份(.+?)
和年份([0-9]+)
也是如此:
在这里,我们将面临其他关键字的问题,如施工
和石油
,我们可以添加至少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,})|(.*?)
试验
正则表达式
如果不需要此表达式,可以在中对其进行修改/更改
正则表达式电路
可视化正则表达式:
使用这些示例进行测试。然后尝试编写regexp以通过测试。这听起来是一个非常具有挑战性的问题,主要是因为用户似乎正在输入纯文本。这意味着他们不知道解析文本的规则,因此你不能期望他们以一致的方式输入任何内容。然后,任何州或国家的缩写也可以是标题的一部分。还有很多其他没人会想到的事情。你能改变API使数据已经被分割成字段吗?有关于示例的文档,所以客户端可能发送的可能性是我考虑的唯一值。如果距离太远,那么我将发送一个错误的请求,并返回一个错误代码,解释文本无效。请参阅文档以获取帮助。匹配项还将报告其位置。尝试匹配您知道其格式的所有子部分。对原始字符串使用区间算术,减去匹配的子部分。然后,删除任何仅由空格组成的不匹配间隔。在那之后,应该最多还有一个间隔。这是你们的标题。@NicoSchertler我到底在做什么我只是有个问题(2014年12月)。有什么建议吗?这很有趣也很有用。。谢谢你的回复
(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);
}
}
}