我提供了一个文本框,用于输入正则表达式以匹配文件名。我计划使用Regex方法GetGroupNames()
检测它们提供的任何命名捕获组。
我想获得他们在每个命名捕获组中输入的表达式。
例如,他们可能会输入这样的正则表达式:
December (?<FileYear>\d{4}) Records\.xlsx
除了手动解析正则表达式字符串之外,是否有方法或手段来获取子表达式\d{4}
?
答案 0 :(得分:1)
这是一个丑陋的强力扩展,用于解析而不使用另一个正则表达式来检测子表达式(或子模式):
public static string GetSubExpression(this Regex pRegex, string pCaptureName)
{
string sRegex = pRegex.ToString();
string sGroupText = @"(?<" + pCaptureName + ">";
int iStartSearchAt = sRegex.IndexOf(sGroupText) + sGroupText.Length;
string sRemainder = sRegex.Substring(iStartSearchAt);
string sThis;
string sPrev = "";
int iOpenParenCount = 0;
int iEnd = 0;
for (int i = 0; i < sRemainder.Length; i++)
{
sThis = sRemainder.Substring(i, 1);
if (sThis == ")" && sPrev != @"\" && iOpenParenCount == 0)
{
iEnd = i;
break;
}
else if (sThis == ")" && sPrev != @"\")
{
iOpenParenCount--;
}
else if (sThis == "(" && sPrev != @"\")
{
iOpenParenCount++;
}
sPrev = sThis;
}
return sRemainder.Substring(0, iEnd);
}
用法如下:
Regex reFromUser = new Regex(txtFromUser.Text);
string[] asGroupNames = reFromUser.GetGroupNames();
int iItsInt;
foreach (string sGroupName in asGroupNames)
{
if (!Int32.TryParse(sGroupName, out iItsInt)) //don't want numbered groups
{
string sSubExpression = reParts.GetSubExpression(sGroupName);
//Do what I need to do with the sub-expression
}
}
现在,如果您想生成测试或样本数据,可以使用名为&#34; Fare&#34;的NuGet包。获得子表达式后,按以下方式:
//Generate test data for it
Fare.Xeger X = new Fare.Xeger(sSubExpression);
string sSample = X.Generate();
答案 1 :(得分:0)
这是一个使用正则表达式匹配正则表达式中的捕获组的解决方案。想法来自这篇文章Using RegEx to balance match parenthesis:
\(\?\<(?<MyGroupName>\w+)\>
(?<MyExpression>
((?<BR>\()|(?<-BR>\))|[^()]*)+
)
\)
或更简洁......
\(\?\<(?<MyGroupName>\w+)\>(?<MyExpression>((?<BR>\()|(?<-BR>\))|[^()]*)+)\)
并使用它可能如下所示:
string sGetCaptures = @"\(\?\<(?<MyGroupName>\w+)\>(?<MyExpression>((?<BR>\()|(?<-BR>\))|[^()]*)+)\)";
MatchCollection MC = Regex.Matches(txtFromUser.Text, sGetCaptures );
foreach (Match M in MC)
{
string sGroupName = M.Groups["MyGroupName"].Value;
string sSubExpression = M.Groups["MyExpression"].Value;
//Do what I need to do with the sub-expression
MessageBox.Show(sGroupName + ":" + sSubExpression);
}
对于原始问题中的示例,消息框将返回FileYear:\d{4}
答案 2 :(得分:0)
此模式(?<=\(\?<\w+\>)([^)]+)
将为您提供所有已命名的匹配捕获表达式以及捕获的名称。它使用负面外观来确保匹配的文本在它之前有(?<...>
。
string data = @"December (?<FileYear>\d{4}) Records\.xlsx";
string pattern = @"(?<=\(\?<\w+\>)([^)]+)";
Regex.Matches(data, pattern)
.OfType<Match>()
.Select(mt => mt.Groups[0].Value)
返回
的一项 \d{4}
虽然(?<FileMonth>[^\s]+)\s+(?<FileYear>\d{4}) Records\.xlsx
等数据会返回两个匹配项:
[^\s]+
\d{4}