0

他の属性を持つタグを含む html 文字列の先頭に値属性を移動する必要があります。

それは私にこのようなものを渡すことができます

<option (attrs1)* value="1" (attrs2)*>...</option>
<option (attrs1)* value='1' (attrs2)*>...</option>
<option (attrs1)* value=1 (attrs2)*>...</option>

そして、それはあるべきです

<option value="1" (attrs1)* (attrs2)*>...</option>
<option value='1' (attrs1)* (attrs2)*>...</option>
<option value=1 (attrs1)* (attrs2)*>...</option>

.Net で Regex を介してどのように行うことができますか?

  • 練習試合です
4

2 に答える 2

3

HtmlAgilityPackを使用してそれを行う方法の例を次に示します。それでも正規表現を使用したい場合は、回答の他の部分を参照してください。

string html = @"<option foo1='bar1' value=""1"" foo=bar></option>";
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);

var node = doc.DocumentNode.ChildNodes[0];
//Get all the attributes
var attributes = new List<HtmlAttribute>(node.Attributes);
//Remove all the attributes
node.Attributes.RemoveAll();

//Insert them again
foreach (var attr in attributes) {
    //If we found the 'value' atrribute, insert it at the begining
    if (attr.Name == "value")
    {
        node.Attributes.Insert(0, attr);
    }
    else {
        node.Attributes.Add(attr);
    }
}

Console.WriteLine(doc.DocumentNode.OuterHtml);

上記のコードは次のように表示されます。

<option value="1" foo="bar" foo1='bar1'>

それはほんの一例でした。HTML のすべてのノードに対してそれを行うことも、必要なノードだけにそれを適用することもできます。


正規表現を使用した別の例。ニーズに 100% 一致するように変更する必要がある場合があります。

string regex = @"<([\w]+)\s+(?:(\w+)=[""']?([^\s""']+)[""']?\s*)+>";
string html = @"<option foo=bar value=""1"" foo2='bar2'>...</option>
                <option foo=bar value=""1"" foo2='bar2'>...</option>
                <option foo=bar value=""1"" foo2='bar2'>...</option>";

//Getting all the matches.
var matches = Regex.Matches(html, regex);
foreach (Match m in matches) {
    //This will contain the replaced string
    string result = string.Format("<{0}", m.Groups[1].Value);

    //Here we will store all the keys
    var keys = new List<string>();
    //Here we will store all the values
    var values = new List<string>();

    //For every pair (key, value) matched
    for (int i = 0; i < m.Groups[2].Captures.Count; i++) {
        //Get the key
        var key = m.Groups[2].Captures[i].Value;
        //Get the value
        var value = m.Groups[3].Captures[i].Value;

        //Insert on the list (if key is 'value', insert at the beginning)
        if (key == "value") {
            keys.Insert(0, key);
            values.Insert(0, value);
        }
        else {
            keys.Add(key);
            values.Add(value);
        }
    }

    //Concatenate all the (key, value) attributes to the replaced string
    for (int i = 0; i < keys.Count; i++) {
        result += string.Format(@" {0}=""{1}""", keys[i], values[i]);
    }

    //Close the tag
    result += ">";

    Console.WriteLine(result);
}

それは印刷されます:

<option value="1" foo="bar" foo2="bar2">
<option value="1" foo="bar" foo2="bar2">
<option value="1" foo="bar" foo2="bar2">
于 2013-02-06T07:59:02.377 に答える
0

免責事項:これはJavascriptベースのソリューションですが、.NetはPythonやRubyなどの他の言語と同じ正規表現のサポートを提供していると思います。したがって、アプローチは有効でなければなりません(言語固有の構文を除く)。単一の正規表現を使用して実行できることを示すためにここにいます。

正規表現の背後にある考え方は、タグの開始、「value=...」の部分、そしてその間のすべてを見つけることです。次に、置換機能を使用して見つかったパーツを再編成し、「値」タグが常に開始タグの直後になるようにします。

わかりました、ここに行きます(Javascriptバージョン):

// some example string
var x = "<something bla=5432 other-st='asdf' value=\"45\"/><p name=asdf value=55fs andalso=\"something\">html like</p>";
x.replace(/(\<(?!\/)[a-z]+)(.+?)?(\ value=(?:\"|\')?[^\"\'\ ]+(?:\"|\')?)/gi, function(a, b, c, d) {return b+d+c;})

更新: C# のバージョンは次のとおりです (fX' による):

string x = "<something bla=5432 other-st='asdf' value=\"45\"/><p name=asdf value=55fs andalso=\"something\">html like</p>";
var r = new Regex("(<(?!/)[a-z]+)(.+?)?(\\sVALUE=(?:\"|')?[^\"'\\s]+(?:\"|')?)", RegexOptions.IgnoreCase);
string s = r.Replace(x, (match) => { return match.Groups[1].Value + match.Groups[3].Value + match.Groups[2].Value; });
于 2013-02-06T08:38:27.553 に答える