http://community.csdn.net/Expert/topic/5653/5653181.xml?temp=.2295496
希望能匹配成对出现的<< >>直接之间的内容,里面可以嵌套<< >>,如
<<Type /Page/Parent 3 0 R/Resources >>
如
Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>能匹配出
<<Type /Page/Parent 3 0 R/Resources >><< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>
希望能匹配成对出现的<< >>直接之间的内容,里面可以嵌套<< >>,如
<<Type /Page/Parent 3 0 R/Resources >>
如
Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>能匹配出
<<Type /Page/Parent 3 0 R/Resources >><< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>
然后在拼一拼,哈。菜鸟就只能写到这个底部了。呼唤小客客。
改进了以下。可以匹配出来了。不过多了2行废的。
稍微修改以下。
yourStr = yourStr.Replace("<<", "∵");
yourStr = yourStr.Replace(">>", "∴");
MatchCollection mc = Regex.Matches(yourStr, @"∵[^∵∴]*(((?'Tag'∵)[^∵∴]*)+((?'-Tag'∴)[^∵∴]*)+)*(?(Tag)(?!))∴");
foreach (Match m in mc)
{
richTextBox2.Text += m.Value.Replace("∵", "<<").Replace("∴", ">>") + "\n";
}这种方法缺点当然是有的,一是无法完全排除源字符串中出现这两个特殊符号的可能,再就是有效率上损失楼主测一下吧,如果有无法匹配的,给下例子
string s = "Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>xxxxx";
Regex re = new Regex("<<(<<(?<BRACKET>)|>>(?<-BRACKET>)|[^<>]*|(?!<)<|(?!>)>)*(?(BRACKET)(?!))>>");
//Regex re = new Regex("<<.*>>");
Match m = re.Match(s);
if (m.Success)
Console.WriteLine(m.Value);
else
Console.WriteLine("No matche");
"...<<<...>>...", //no match
"...<<<...>>>...", //no match,
"...<<...>>>...", //no match
"...<<.<<<..>>>..>>...",
"...<<..<<<...>>.>>>...", //no match
"<<Type /Page/Parent 3 0 R/Resources >>",
"Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>",
"Type /Page/Parent 3 0 R/Resources <<< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>"
};
Regex re = new Regex("(?<!<)<<(?!<)((?<!<)<<(?!<)(?<BRACKET>)|(?<!>)>>(?!>)(?<-BRACKET>)|.)*(?(BRACKET)(?!))(?<!>)>>(?!>)"); foreach(string s in slist)
{
Console.WriteLine("{0}*****:",s);
Match m = re.Match(s);
if (m.Success)
Console.WriteLine(m.Value);
else
Console.WriteLine("No match");
}
-----------------------------
<<和>>之间是有可能出现单独的<或> ,但会以\< \>这样的形式出现
要么就是<>成对出现
-----------------------------楼上的正则可以满足这一条件,但是类似于
Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>
这样的字符串,匹配结果为
<< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>
把后面多余的/MediaBox [0 0 612 792] /Contents 5 0 R>>也匹配出来了请思归老大再看一下。另外我觉得直接匹配的方法写起来比较麻烦,需要考虑的情况太多,就算能匹配成功,需要做的判断太多,效率也会比较低。是否这样,还请指教。如果有有关正则效率方面的书籍或文章请给推荐一下,谢谢!
"...<<<...>>...", //no match
"...<<<...>>>...", //no match,
"...<<...>>>...", //no match
"...<<.<<<..>>>..>>...",
"...<<..<<<...>>.>>>...",
"<<Type /Page/Parent 3 0 R/Resources >>",
"Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>",
"Type /Page/Parent 3 0 R/Resources <<< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>","Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>",
"..<<.....>>....>>..>>",
"..>>.....<<....>>",
"..<<< << <<....<<<.>>....>>..>>...>>.."
}; Regex re = new Regex("(?<!<)<<(?!<)((?<!<)<<(?!<)(?<BRACKET>)|(?<!>)>>(?!>)(?<-BRACKET>)|[^<>]+|(?<!<)<(?!<)|(?<!>)>(?!>)|<{3,}|>{3,})*(?(BRACKET)(?!))(?<!>)>>(?!>)"); foreach(string s in slist)
{
Console.WriteLine("{0}*****:",s);
Match m = re.Match(s);
if (m.Success)
Console.WriteLine(m.Value);
else
Console.WriteLine("No match");
}
这样就不用替换了哦。可以匹配
3243df<<<fds>>>lioi这样的字串了
貌似只有过客的能匹配正确。
这个只是正则的一部分,调试了半天,发现是后面的匹配模式问题
我原来那部分是匹配<<>>嵌套用的是
((?'o'(<<))(((?=(<<))(?'o'(<<)))|((?=(>>))(?'-o'(>>)))|([\S\s]*?(?=(>>)|(<<))))+?(?'-o'(>>))(?(o)(?!))),
谢谢各位了,偶再调试调试
------------------------------------------------------------------
多谢思归Regex re = new Regex("(?<!<)<<(?!<)((?<!<)<<(?!<)(?<BRACKET>)|(?<!>)>>(?!>)(?<-BRACKET>)|[^<>]+|(?<!<)<(?!<)|(?<!>)>(?!>)|<{3,}|>{3,})*(?(BRACKET)(?!))(?<!>)>>(?!>)");
---------------------------------
这个正则在匹配上面所列各种情况没有问题,但是类似于
<<abc<<def>>
这种前面多了<<的情况时,简单的没问题,但是复杂一些的,如
Type /<<Page/Parent 3 0 R/<<Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>
可能是由于回溯匹配的关系,多重循环尝试匹配,最终导致程序崩溃((?'o'(<<))(((?=(<<))(?'o'(<<)))|((?=(>>))(?'-o'(>>)))|([\S\s]*?(?=(>>)|(<<))))+?(?'-o'(>>))(?(o)(?!)))
---------------------------
楼主的这个正则也是这样的问题,虽然不会导致程序崩溃,但匹配结果是不正确的
<<abc<<def>>
另外,楼主说这个只是正则的一部分,个人觉得正则不要写得太复杂,一是调试困难,再就是正则太复杂,容易出现效率陷阱,还有就是调试时没有发现bug,发布后一旦出错,排错就很麻烦了
----------------------------------
在我这里用
Type /<<Page/Parent 3 0 R/<<Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>
这样的字符串测试还是会导致程序崩溃感谢思归的指点,明天开始回家一周左右,只能回来再探讨这一问题了
{string[] slist ={"...<<...>>...", //match
"...<<<...>>...", //no match
"...<<<...>>>...", //no match,
"...<<...>>>...", //no match
"...<<.<<<..>>>..>>...",
"...<<..<<<...>>.>>>...",
"<<Type /Page/Parent 3 0 R/Resources >>",
"Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>",
"Type /Page/Parent 3 0 R/Resources <<< /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>","Type /Page/Parent 3 0 R/Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>",
"..<<.....>>....>>..>>",
"..>>.....<<....>>",
"..<<< << <<....<<<.>>....>>..>>..>>>>.>>..",
"Type /<<Page/Parent 3 0 R/<<Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>xxxxxxxxxx",
"Type /<<Page/Parent 3 0 R/<<Resources << /Font << /F1 7 0 R >>/ProcSet 6 0 R >>/MediaBox [0 0 612 792] /Contents 5 0 R>>"
}; Regex re = new Regex("(?<!<)<<(?!<)(?>(?<!<)<<(?!<)(?<BRACKET>)|(?<!>)>>(?!>)(?<-BRACKET>)|[^<>]+|(?<!<)<(?!<)|(?<!>)>(?!>)|<{3,}|>{3,})*(?(BRACKET)(?!))(?<!>)>>(?!>)"); foreach(string s in slist)
{
Console.WriteLine("{0}*****:",s);
Match m = re.Match(s);
if (m.Success)
Console.WriteLine(m.Value);
else
Console.WriteLine("No match");
}
}
<<fds<<f<d>s>>fd>>
<<f<<d<<s<<f>>d>>s>>fd>>
谢谢,楼上。我改进了一下,这下行了吧。
<<ewrewr<<53443534<<43243<<dfsfds<<fdfds>>fdsf>>13213>>4324324>>423432>>
看看要几秒出结果
-----------------
临行前又测了一下,这回没问题了,再可能存在的问题也就是<<<这样连续的情况了,这个就要根据需求来定了刚开始学习使用平衡组,回来后再仔细研究一下