我需要在包含带有其他属性的标记的html字符串的开头移动一个value属性。
它可以传递给我这样的东西
<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完成?
答案 0 :(得分: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上的所有节点执行此操作,或者只将其应用于您需要的节点等。
使用Regex的另一个例子。您可能需要修改以满足您的需求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">
答案 1 :(得分: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; });