求一c#正则表达式

ccb8888 2008-12-07 08:45:30
string content = "
<div id="data">
<div class="reg1">12312</div>
<input type="hidden">
<div class="reg2">12312</div>
<input type="hidden">
<div class="reg1">12312</div>
<input type="hidden">
<div class="reg2">12312</div>
<input type="hidden">
<div class="reg1">12312</div>
<input type="hidden">
<div class="reg2">12312</div>
<input type="hidden">
</data>
"
我要截取的是12312这个内容,要求表达式必须包含reg1或者是reg2,因为我的每个div里面还嵌套很多标签,12312这个只是随便输上去的内容。
...全文
108 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Fourix 2008-12-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 root_ 的回复:]
你这样匹配不到主要是因为小数点“.”是不能匹配换行符的,所以要把小数点换个[\s\S],以匹配任意字符
[/Quote]
RegexOptions.Singleline可以让“.”匹配所有字符呢
一品梅 2008-12-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ccb8888 的回复:]
我之前也是这样想,可是下面的表达式怎么不行
(( <div class=list_li_)|( <div class=list_li_ li_bg)).+? <input type="hidden">
[/Quote]
这怎么可能匹配你的要求呢?
root_ 2008-12-07
  • 打赏
  • 举报
回复
希望楼主记住一点,通常情况下,|的分支越多,每个分支中表达式的长度越长,匹配的效率就越低
另外在不需要用到()的地方,也尽量的少用(),同样会降低效率
root_ 2008-12-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ccb8888 的回复:]
我之前也是这样想,可是下面的表达式怎么不行
((<div class=list_li_)|(<div class=list_li_ li_bg)).+?<input type="hidden">
[/Quote]

你这样匹配不到主要是因为小数点“.”是不能匹配换行符的,所以要把小数点换个[\s\S],以匹配任意字符
((<div class=list_li_)|(<div class=list_li_ li_bg))[\s\S]+?<input type="hidden">


这样写是可以匹配成功了,但如果仔细查看一下结果,你会发现它同样是不对的
(<div class=list_li_ li_bg)
这个分支在你给的例子中是永远不会参与匹配的,因为如果有左侧的一个分支匹配成功后,就不会再去尝试右侧的分支了
所以在<div class=list_li_ li_bg>12312 </div>子串中是由(<div class=list_li_)这个分支来匹配字符串的<div class=list_li_,而由[\s\S]+?来匹配bg>12312 </div>

如果在每个分支后面加上一个必须匹配的普通字符,就相当于加了一个限定,这时候后面的分支就可以匹配到了
((<div class=list_li_>)|(<div class=list_li_ li_bg>))[\s\S]+?<input type="hidden">


更进一步的,提取尽可能多的相同部分,只有不同部分才用|表示或的关系,这样可以提高匹配效率
(<div class=list_li_(| li_bg)>)[\s\S]+?<input type="hidden">
//可以简化为
(<div class=list_li_( li_bg)?>)[\s\S]+?<input type="hidden">


呵呵,其实我3楼的代码,因为没看清楼主的源字符串,也犯了上面说的错误,虽然结果是一样的,但是后面的(bg)?同样没有匹配到,需要改一下
            MatchCollection mc = Regex.Matches(content, @"(?<=<div\s+class=list_li_( li_bg)?[^>]*>)[^<>]*(?=</div>)", RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}

Fourix 2008-12-07
  • 打赏
  • 举报
回复

string content = @"
<div id=""data"">
<div class=list_li_>12311 </div>
<input type=""hidden"">
<div class=reg2>12312 </div>
<input type=""hidden"">
<div class=list_li_>12313 </div>
<input type=""hidden"">
<div class=reg2>12314 </div>
<input type=""hidden"">
<div class=list_li_>12315 </div>
<input type=""hidden"">
<div class=reg2>12316 </div>
<input type=""hidden"">
</data>
";
textBox1.Text = "";
MatchCollection mc1 = Regex.Matches(content, @"(<div class=(?<class>list_li_)>|<div class=(?<class>reg2)>)(?<cont>.*?)</div>", RegexOptions.Singleline);
foreach (Match m1 in mc1)
{
textBox1.Text += m1.Groups["class"].Value + " " + m1.Groups["cont"].Value + "\r\n";

}
,
ccb8888 2008-12-07
  • 打赏
  • 举报
回复
我之前也是这样想,可是下面的表达式怎么不行
(( <div class=list_li_)|( <div class=list_li_ li_bg)).+? <input type="hidden">
root_ 2008-12-07
  • 打赏
  • 举报
回复
那就用|隔开,然后用()括起来,表示或的关系,尽量提取相同部分,不同部分用(str1|str2|str3)这种形式,以提高匹配效率

MatchCollection mc = Regex.Matches(content, @"(?<=<div\s+class=(list_li_|reg2)[^>]*>)[^<>]*(?=</div>)", RegexOptions.IgnoreCase);
ccb8888 2008-12-07
  • 打赏
  • 举报
回复
千年,这50分是归你的了,不过我还想再请教多一次你。
string content = @"
<div id=""data"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=reg2>12312 </div>
<input type=""hidden"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=reg2>12312 </div>
<input type=""hidden"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=reg2>12312 </div>
<input type=""hidden"">
</data>
";
因为刚才的class的名称恰好有点相似,假如现在像我上面的字符窜,两个的class名称都完全不相同,那表达式该怎么写呢?
root_ 2008-12-07
  • 打赏
  • 举报
回复
再晕,呵呵

            string content = @"
<div id=""data"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=list_li_ li_bg>12312 </div>
<input type=""hidden"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=list_li_ li_bg>12312 </div>
<input type=""hidden"">
<div class=list_li_>12312 </div>
<input type=""hidden"">
<div class=list_li_ li_bg>12312 </div>
<input type=""hidden"">
</data>
";
MatchCollection mc = Regex.Matches(content, @"(?<=<div\s+class=list_li_(bg)?[^>]*>)[^<>]*(?=</div>)", RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
richTextBox1.Text += m.Value + "\n";
}
ccb8888 2008-12-07
  • 打赏
  • 举报
回复
晕倒,本想偷懒下,把class的名称写成简单,呵呵,我写全一点吧。
string content = "
<div id="data">
<div class=list_li_>12312 </div>
<input type="hidden">
<div class=list_li_ li_bg>12312 </div>
<input type="hidden">
<div class=list_li_>12312 </div>
<input type="hidden">
<div class=list_li_ li_bg>12312 </div>
<input type="hidden">
<div class=list_li_>12312 </div>
<input type="hidden">
<div class=list_li_ li_bg>12312 </div>
<input type="hidden">
</data>
"
我自己写的:((<div class=list_li_)|(<div class=list_li_ li_bg)).+?<input type="hidden">
可是不行。。
root_ 2008-12-07
  • 打赏
  • 举报
回复
这例子给的,怎一个汗字了得。。。

            string content = @" 
<div id=""data"">
<div class=""reg1"">12312 </div>
<input type=""hidden"">
<div class=""reg2"">12312 </div>
<input type=""hidden"">
<div class=""reg1"">12312 </div>
<input type=""hidden"">
<div class=""reg2"">12312 </div>
<input type=""hidden"">
<div class=""reg1"">12312 </div>
<input type=""hidden"">
<div class=""reg2"">12312 </div>
<input type=""hidden"">
</data>
";
MatchCollection mc = Regex.Matches(content, @"(?<=<div\s+class=""reg[12]""[^>]*>)[^<>]*(?=</div>)", RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
richTextBox1.Text += m.Value + "\n";
}

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧