我确定这个问题已被问到某个地方(也许在这里),但我找不到任何信息,这可能是由于我不确定如何准确描述它。
基本上,我正在寻找一个高级查找和替换。替换我确定我可以弄清楚它是什么,但现在我无法让这个发现工作。
在应用程序中,有很多htm文件被加载。用户选择文件并使用它执行操作。完成此操作后,我希望系统再次扫描文件以确保没有问题。例如,此字符串可能出现在htm文件中:
<?strange_tag_start
name="var_value" ?>Name<?strange_tag_end ?>
而且,是的,它可以在这样的线条之间被打破。除非发生这种情况,否则上述问题不是问题:
<?strange_tag_start
name="var_value" ?><?strange_tag_start
name="var_value" ?>Name<?strange_tag_end ?><?strange_tag_end ?>
换行符可能不同。我想要做的是在文档中搜索包含<?strange_tag
然后包含<?strange_tag_end ?>
的字符串。如果它找到了,我想在字符串中检查是否有另一个<?strange_tag_start
或另一个<?strange_tag_end ?>
。
我最初尝试读取文件并获取特定值的每个索引,然后尝试比较它们。但是,文件中可能存在以下内容,这些都是完全正常的,但系统会找到它们并为我标记它们:
<?strange_tag_start
name="var_value" ?>Name<?strange_tag_end ?> There is other text here
and some more text on another line. Then this <?strange_tag_start name="var_value"
?>Name<?strange_tag_end ?> is present.
它归结为一个系统(例如某些应用程序中存在的系统),其中指定了字符串的开头,指定了字符串的结尾,然后系统检查它是否包含字符串。
如果这没有意义,或者你需要更多澄清,我可以这样做。
更新
让我澄清一下。我有以下多行字符串:
I want to preserve<?start_foo
bar="value" ?> the content
<?start_baz qux="value" ?>Name
<?end-baz_qux ?>that is between weird tags.
我想找<?start_foo bar="value"
我还想找到<?end-baz_qux ?>
(注意:其中可能有两个紧挨着。)
找到后,我想检查该字符串中是否有另一个<?start_foo bar=
(注意:该标签中的“值”也可能不同。)
然后我想删除不应该存在的中间内容,所以我最终得到:
I want to preserve<?start_foo
bar="value" ?> the content
<?end-baz_qux ?>that is between weird tags.
这是另一个希望让它更清晰的例子:
Back <?rh-udv_start name="ctrl_btn" ?><?rh-udv_start name="ctrl_btn"
?>button<?rh-udv_end ?><?rh-udv_end ?> to
在进行搜索之后,我应该最终得到这个:
Back <?rh-udv_start name="ctrl_btn" ?>button<?rh-udv_end ?> to
基本上,我正在寻找一种说法:
答案 0 :(得分:2)
我相信
<\?.*?\?>
可以找到大多数正则表达式的标签(包括Visual Studio的 - 不确定你使用的是什么)。
如果您还想更换奇怪标签之间的内容,那么请您告诉我们一个更现实的例子吗?确切地知道您要匹配的内容(或一些非常接近的近似值)以提供正确的正则表达式至关重要。例如
<?start_strange_tag blah="foo"?>Name<?end_strange_tag?>
与
非常不同<?foo bar="baz"?>Name<?/foo?>
与
不同<?start_foo bar="baz"?>Name<?foo_end?>
等
<强>更新强>
根据您在下面的评论,我将假设您有一个如下所示的文档:
I want to preserve<?start_foo
bar=\"value\" ?> the content
<?start_baz qux=\"value\" ?>Name
<?end-baz_qux ?>that is not between weird tags.
并且您希望结果为:
I want to preserve the content
that is not between weird tags.
我还假设您正在使用.NET正则表达式程序集(而不是Visual Studio内置的正则表达式。是的,它们是不同的。)
如果是这种情况,那么您可以使用以下内容:
static void Main( string[] args )
{
string l_input =
"I want to preserve<?start_foo \n" +
" bar=\"value\" ?> the content\n" +
"<?start_baz qux=\"value\" ?>Name\n" +
"<?end-baz_qux ?>that is not between weird tags.";
string[] l_singleTags = { "foo" };
string[] l_multiTags = { "baz" };
// Removing the single tags is easy:
foreach ( var l_singleTag in l_singleTags )
l_input = Regex.Replace( l_input, @"<\?start_" + Regex.Escape( l_singleTag ) + @"\b.*?\?>", "", RegexOptions.Singleline );
// Removing the multi tags is not too bad:
foreach ( var l_multiTag in l_multiTags )
l_input = Regex.Replace( l_input, @"<\?start_" + Regex.Escape( l_multiTag ) + @" (?<param>\w+).*?\?>.*?<\?end-" + Regex.Escape( l_multiTag ) + @"_\k<param>.*?\?>", "", RegexOptions.Singleline );
Console.WriteLine( l_input );
Console.ReadKey( true );
}
l_input
变为:
I want to preserve the content
that is not between weird tags.
更新2
在回答您的问题更新时,请尝试以下代码:
static void Main( string[] args )
{
string l_input =
"Back <?rh-udv_start name=\"ctrl_btn\" ?><?rh-udv_start name=\"ctrl_btn\"" +
" ?>button<?rh-udv_end ?><?rh-udv_end ?> to";
l_input = Regex.Replace( l_input, @"<\?(?<tagname>[-a-z]+_[a-z]+).*?\?>(?=<\?\k<tagname>)", "", RegexOptions.Singleline );
Console.WriteLine( l_input );
Console.ReadKey( true );
}
l_input
变为:
Back <?rh-udv_start name="ctrl_btn" ?>button<?rh-udv_end ?> to
它只是查找重复标记并删除它。例如:
<?a_start foo="bar"?><?a_start foo="bar"
?>
第一个标签将被删除,只留下:
<?a_start foo="bar"
?>
与结束标签相同。代码不会容忍标签之间的空格或内容(在这种情况下,它不会删除任何标签)。在您拥有所需内容之前,请随意使用该示例。
答案 1 :(得分:0)
您可以使用Html Agility Pack。我已经将它用于类似的东西,在HTML中定位引文并用序号替换ID。在我的情况下,搜索和替换看起来像这样:
var doc = new HtmlDocument();
doc.LoadHtml(html);
// find using xpath expression
var citeNodes = doc.DocumentNode.SelectNodes("//cite[@data-citationid]");
foreach (var node in citeNodes)
{
// do some other stuff
node.Name = "a";
node.SetAttributeValue("id", "r" + citation.CitationId);
node.InnerHtml = "[" + citation.Ordinal + "]";
}
return doc.DocumentNode.InnerHtml;