私が次の正規表現を持っていると仮定しましょう:
-(\d+)-
そして、C#を使用して、グループ1 (\d+)
をAA
に置き換えて、以下を取得します。
-AA-
今、私はそれを使って置き換えています:
var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, "-AA-");
しかし、_(\d+)_
に一致するようにパターンを変更すると、_AA_
による置換文字列も変更する必要があり、これはDRY原則。
私は次のようなものを探しています:
一致したテキストを正確に保持しますが、グループ1をthis text
で変更し、グループ2をanother text
で変更します...
編集:
これはほんの一例です。上記のことを行う一般的な方法を探しています。
動作するはずです:
anything(\d+)more_text
および想像できるパターン。
私がやりたいのは、グループのみを置き換え、残りの試合を維持することです。
グループを識別する必要があるかどうかにかかわらず、すべてをグループ内にカプセル化することをお勧めします。そうすれば、置換文字列でそれらを使用できます。例えば:
var pattern = @"(-)(\d+)(-)";
var replaced = Regex.Replace(text, pattern, "$1AA$3");
またはMatchEvaluatorを使用して:
var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value + "AA" + m.Groups[3].Value);
もう少し面倒な方法は、後読み/先読みを使用することです。
(?<=-)(\d+)(?=-)
lookahead and lookbehind を使用してこれを行うことができます。
var pattern = @"(?<=-)\d+(?=-)";
var replaced = Regex.Replace(text, pattern, "AA");
私もこれが必要で、次の拡張メソッドを作成しました。
public static class RegexExtensions
{
public static string ReplaceGroup(
this Regex regex, string input, string groupName, string replacement)
{
return regex.Replace(
input,
m =>
{
var group = m.Groups[groupName];
var sb = new StringBuilder();
var previousCaptureEnd = 0;
foreach (var capture in group.Captures.Cast<Capture>())
{
var currentCaptureEnd =
capture.Index + capture.Length - m.Index;
var currentCaptureLength =
capture.Index - m.Index - previousCaptureEnd;
sb.Append(
m.Value.Substring(
previousCaptureEnd, currentCaptureLength));
sb.Append(replacement);
previousCaptureEnd = currentCaptureEnd;
}
sb.Append(m.Value.Substring(previousCaptureEnd));
return sb.ToString();
});
}
}
使用法:
var input = @"[Assembly: AssemblyFileVersion(""2.0.3.0"")][Assembly: AssemblyFileVersion(""2.0.3.0"")]";
var regex = new Regex(@"AssemblyFileVersion\(""(?<version>(\d+\.?){4})""\)");
var result = regex.ReplaceGroup(input , "version", "1.2.3");
結果:
[Assembly: AssemblyFileVersion("1.2.3")][Assembly: AssemblyFileVersion("1.2.3")]
パターンを変更したくない場合は、一致したグループのグループインデックスと長さプロパティを使用できます。
var text = "example-123-example";
var pattern = @"-(\d+)-";
var regex = new RegEx(pattern);
var match = regex.Match(text);
var firstPart = text.Substring(0,match.Groups[1].Index);
var secondPart = text.Substring(match.Groups[1].Index + match.Groups[1].Length);
var fullReplace = firstPart + "AA" + secondPart;
パターンを変更する必要のないもう1つの素晴らしいクリーンオプションを次に示します。
var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, (_match) =>
{
Group group = _match.Groups[1];
string replace = "AA";
return String.Format("{0}{1}{2}", _match.Value.Substring(0, group.Index - _match.Index), replace, _match.Value.Substring(group.Index - _match.Index + group.Length));
});
以下のコーディングを行って、個別のグループ置換を取得します。
new_bib = Regex.Replace(new_bib, @"(?s)(\\bibitem\[[^\]]+\]\{" + pat4 + @"\})[\s\n\v]*([\\\{\}a-zA-Z\.\s\,\;\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']{20,70})", delegate(Match mts)
{
var fg = mts.Groups[0].Value.ToString();
var fs = mts.Groups[1].Value.ToString();
var fss = mts.Groups[2].Value.ToString();
fss = Regex.Replace(fss, @"[\\\{\}\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']+", "");
return "<augroup>" + fss + "</augroup>" + fs;
}, RegexOptions.IgnoreCase);