1

.net Regex クラスを使用して特定のキャプチャ グループを置換することは可能ですか。

例えば

<customer.*?(display="(?:yes|no)")?.*?>

Customer xml 要素で照合したいのですが、表示属性キャプチャ グループ内で置き換えます。それはグループ 1 になると思いますが、いつでもこれに名前を付けることができます。

4

2 に答える 2

2

display属性の前後にあるものをキャプチャする必要があると思います。

(<customer.*?)(display="(?:yes|no)")(.*?>) 

その後、それを置換ラムダで使用できます

Regex.Replace(inputString, @"(<customer.*?)(display=""(?:yes|no)"")(.*?>)", m => String.Format("{0}{1}{2}", m.Groups[1], /* replacement string based on m.Groups[2] */, m.Groups[3]));
于 2012-10-08T05:28:16.963 に答える
0

Andrewsの回答に基づいて、置換を処理するメソッドを作成することにより、これを少し拡張しました。私の状況では、グループ全体を置き換えたかったので、これを行うためのヘルパークラスを作成しました。また、これを実現するためにキャプチャ前後のグループを作成する必要はありません。

/// <summary>
/// A Regular Expression match and replace class
/// </summary>
public class RegexReplacer
{
    private readonly int _captureGroupToReplace;

    /// <summary>
    /// Initialises the RegEx replacer with matching criteria.
    /// </summary>
    /// <param name="name">A name that identifies this replacement pattern</param>
    /// <param name="matchCriteria">A regular Expression used to locate the values to replace</param>
    /// <param name="replacementValue">The value that will replace the matched pattern</param>
    /// <param name="captureGroupToReplace">The Capture group that should be replaced. The default is the entire match</param>
    public RegexReplacer(string name, Regex matchCriteria, string replacementValue, int captureGroupToReplace = 0)
    {
        _captureGroupToReplace = captureGroupToReplace;
        Name = name;
        ReplacementValue = replacementValue;
        MatchCriteria = matchCriteria;
    }

    public string Name { get; set; }

    public Regex MatchCriteria { get; set; }

    public string ReplacementValue { get; set; }

    /// <summary>
    /// Finds and replaces all instances of a string within the supplied string or replaces a group if the group id is supplied in the constructor
    /// </summary>
    public string ReplaceInString(string stringToSearch)
    {
        if (_captureGroupToReplace != 0)
            return MatchCriteria.Replace(stringToSearch, new MatchEvaluator(ReplaceGroup));

        return MatchCriteria.Replace(stringToSearch, ReplacementValue);
    }

    private string ReplaceGroup(Match match)
    {
        try
        {
            var matchedString = match.Value;
            //Match index is based on the original string not the matched string
            int groupIndex = match.Groups[_captureGroupToReplace].Index - match.Index;
            int groupLength = match.Groups[_captureGroupToReplace].Length;

            var preGroupString = matchedString.Substring(0, groupIndex);
            var postGroupString = matchedString.Substring(groupIndex + groupLength, matchedString.Length - (groupIndex + groupLength));

            var replacedString = String.Format("{0}{1}{2}", preGroupString, ReplacementValue, postGroupString);

            return replacedString;
        }
        catch (Exception)
        {
            return match.Value;
        }
    }
}

また、元のパターンを変更して、xmlの最後に空のグループが表示され、属性が存在しない場合は属性を挿入する必要がありました。使用法は次のようになります。

var replacer = new RegexReplacer("DisplayCustomerAttribute",
                 new Regex(@"(?:<customer\s.*?((\sdisplay=""(?:yes|no)"").*?|())>)"),
                 @" display=""yes""", 1)
 xmlString = replacer.ReplaceInString(xmlString);

補足として、これの理由は、値がデフォルトと同じである場合、.netxmlシリアル化に属性が含まれないためです。これは、あなたが消費者を管理している場合は問題ありませんが、私たちの場合はそうではないので、明示する必要があります。

于 2012-10-08T22:32:25.317 に答える