Как изменить другой формат текста в один формат в C#
Я задаю вопрос о контексте анологии. Допустим, у меня есть разные формы дат, и я хочу преобразовать их в один формат. Я сделал это с помощью кода ниже
string[] dates =
{
"december-21-2016",
"december, 28,2016",
"27 january,2017",
"29 december,2016",
"03 mar 1990"
};
string[] formattedDates = new string[dates.Length];
string[] formats = { "MMMM-dd-yyyy","MMMM, dd,yyyy","MMMM, d,yyyy","dd MMMM,yyyy","dd MMM yyyy" };
for (int i = 0; i < dates.Length; i++)
{
DateTime date;
if (DateTime.TryParseExact(dates[i], formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
formattedDates[i] = date.ToString("dd/MM/yyyy");
Console.WriteLine(formattedDates[i]);
}
вот выходной 21-12-2016, 28-12-2016, 27-01-2017, 29-12-2016, 03-03-1990,
Я хочу написать тот же код, но для текста, а не даты, как
string[] formats=
{
"Husband and Wife",
"Wife and Husband",
"Husband and Wife",
"Wife and Husband",
"hus & wife",
"H & W",
};
но вывод должен быть "H and W", для всех форматов выше. Будет лучше, если мы сможем сделать это с помощью linq.
извините за плохой английский и форматирование, я новичок в этом.
1 ответ
В то время как DateTime
имеет несколько простой способ их анализа на основе формата, с другими текстовыми формами может быть сложнее иметь дело.
Я не уверен, что Regex лучше всего подходит для такого сценария, однако вы можете порекомендовать себя из приведенного ниже кода, чтобы добиться анализа текста:
public class RegexTextCalibrator
{
private ICollection<Tuple<Regex, string>> Calibrations = new List<Tuple<Regex, string>>();
public void AddParallelPattern(IEnumerable<string> a, IEnumerable<string> b, string output)
{
this.AddParallelPattern(a, b, @"\W+.*", output);
}
public void AddParallelPattern(IEnumerable<string> a, IEnumerable<string> b, string inBetweenLinkPattern, string output)
{
string subPatternA = String.Join("|", a);
string subPatternB = String.Join("|", b);
var patternA = String.Format("({0})({1})({2})", subPatternA, inBetweenLinkPattern, subPatternB);
var patternB = String.Format("({0})({1})({2})", subPatternB, inBetweenLinkPattern, subPatternA);
this.Add(String.Format("{0}|{1}", patternA, patternB), output);
}
public void Add(string pattern, string output)
{
this.Add(new Regex(pattern, RegexOptions.IgnoreCase), output);
}
public void Add(Regex regex, string output)
{
Calibrations.Add(new Tuple<Regex, string>(regex, output));
}
public string Resolve(string value)
{
var calibration = this.Calibrations.FirstOrDefault(x => x.Item1.IsMatch(value));
return calibration != null ? calibration.Item2 : null;
}
}
Редактировать Ниже прокомментировано использование приведенного выше кода.
Вы можете использовать класс следующим образом:
// configure the calibration/mapping.
var calibrator = new RegexTextCalibrator();
calibrator.AddParallelPattern(
new[] { "husband", "hus", "h" }, // defines one side of the pattern
new[] { "wife", "w" }, // defines the other side of the pattern
"H and W"); // defines the result
// the inputs that will be mapped
var inputs = new string[] {
"Husband and Wife",
"Wife and Husband",
"Husband and Wife",
"Wife and Husband",
"hus & wife",
"H & W"
};
// loops through the inputs and map them to the desired value
foreach (var input in inputs)
Console.WriteLine(calibrator.Resolve(input)); // prints "H and W"...