我正在嘗試從基于格式的字串中獲取一些單獨的值,現在這種格式可以非常理想地改變,我想使用另一個字串來指定它。
例如,假設我的輸入是1. Line One - Part Two (Optional Third Part)我想指定匹配的格式%number%. %first% - %second% (%third%),然后我希望這些值作為變數。
現在我能想到的唯一方法是使用 RegEx 組,而我幾乎得到了 RegEx 的作品。
var input = "1. Line One - Part Two (Optional Third Part)";
var formatString = "%number%. %first% - %second% (%third%)";
var expression = new Regex("(?<Number>[^.] ). (?<First>[^-] ) - (?<Second>[^\\(] ) ((?<Third>[^)] ))");
var match = expression.Match(input);
Console.WriteLine(match.Groups["Number"].ToString().Trim());
Console.WriteLine(match.Groups["First"].ToString().Trim());
Console.WriteLine(match.Groups["Second"].ToString().Trim());
Console.WriteLine(match.Groups["Third"].ToString().Trim());
這會產生以下輸出,所以除了那個左括號之外一切都很好。
1 第一行第二部分(可選第三部分
對于如何將格式字串轉換為正則運算式,我現在有點迷茫,現在這種格式沒有規則,但它需要對用戶來說相當容易。
非常感謝任何建議,或者也許還有另一種不涉及正則運算式的方法?
uj5u.com熱心網友回復:
你可以使用這個正則運算式:
^(?<Number>[^.] )\. (?<First>[^-] ) - (?<Second>[^(] )(?: \((?<Third>[^)] )\))?$

如果你想保持你的語法,你可以利用Regex.Escape方法。我還撰寫了一些代碼來決議其中的所有引數%
using System.Text.RegularExpressions;
var input = "1. Line One - Part Two (Optional Third Part)";
var formatString = "%number%. %first% - %second% (%third%)";
formatString = Regex.Escape(formatString);
var parameters = new List<string>();
formatString = Regex.Replace(formatString, "%([^%] )%", match =>
{
var paramName = match.Groups[1].Value;
var groupPattern = "(?<" paramName ">{" parameters.Count "})";
parameters.Add(paramName);
return groupPattern;
});
var pattern = string.Format(
formatString,
"[^\\.] ",
"[^\\-] ",
"[^\\(] ",
"[^\\)] ");
var match = Regex.Match(input, pattern);
foreach (var paramName in parameters)
{
Console.WriteLine(match.Groups[paramName]);
}
補充說明
您需要調整為每個組指定模式的部分,目前它不是通用的,也不關心會有多少引數。
所以最后,考慮到這一切并稍微清理一下代碼,你可以使用這樣的解決方案:
public static class FormatBasedCustomRegex
{
public static string GetPattern(this string formatString,
string[] subpatterns,
out string[] parameters)
{
formatString = Regex.Escape(formatString);
formatString = formatString.ReplaceParams(out var @params);
if(@params.Length != subpatterns.Length)
{
throw new InvalidOperationException();
}
parameters = @params;
return string.Format(
formatString,
subpatterns);
}
private static string ReplaceParams(
this string formatString,
out string[] parameters)
{
var @params = new List<string>();
var outputPattern = Regex.Replace(formatString, "%([^%] )%", match =>
{
var paramName = match.Groups[1].Value;
var groupPattern = "(?<" paramName ">{" @params.Count "})";
@params.Add(paramName);
return groupPattern;
});
parameters = @params.ToArray();
return outputPattern;
}
}
主要方法如下所示:
var input = "1. Line One - Part Two (Optional Third Part)";
var pattern = "%number%. %first% - %second% (%third%)".GetPattern(
new[]
{
"[^\\.] ",
"[^\\-] ",
"[^\\(] ",
"[^\\)] ",
},
out var parameters);
var match = Regex.Match(input, pattern);
foreach (var paramName in parameters)
{
Console.WriteLine(match.Groups[paramName]);
}
但這取決于您如何定義特定方法以及它們應該具有哪些簽名才能讓您擁有最好的代碼:)
uj5u.com熱心網友回復:
您的格式包含正在成為正則運算式一部分的特殊字符。您可以使用該Regex.Escape方法來處理它。之后,您可以使用 aRegex.Replace和委托將格式轉換為正則運算式:
var input = "1. Line One - Part Two (Optional Third Part)";
var fmt = "%number%. %first% - %second% (%third%)";
var templateRE = new Regex(@"%([a-z] )%", RegexOptions.Compiled);
var pattern = templateRE.Replace(Regex.Escape(fmt), m => $"(?<{m.Groups[1].Value}>. ?)");
var ansRE = new Regex(pattern);
var ans = ansRE.Match(input);
注意:您可能希望將^和分別$放在開頭和結尾pattern,以確保格式必須與整個輸入字串匹配。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/516484.html
標籤:C#正则表达式细绳
