正则表达式 “双向最小匹配”

简介: 最近做一个 字符串查找的例子从字符串中提取制定内容

如下:



 String input = " <a  href=\" <a  href=\"authentication.html?file=KF619L_Z.pdf\" class=\"icondrawing balloonbtn\"  

  rel=\"shadowbox;width=720\">外観図面</a>";


需要提取   "authentication.html?file=KF619L_Z.pdf"


代码 如下:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Threading.Tasks;

namespace regDemo

{

   class Program

   {

       static void Main(string[] args)

       {

           String input = " <a  href=\" <a  href=\"authentication.html?file=KF619L_Z.pdf\" class=\"icondrawing balloonbtn\"  rel=\"shadowbox;width=720\">外観図面</a>";

           Console.WriteLine(getCenterString(input, "href=\"", "\" class="));

           Console.ReadKey();

       }

       public static String getCenterString(String input,String left,String right)

       {

           Match match = Regex.Match(input, left + "(.+?)" + right);

           while (match.Success)

           {

               return match.Groups[1].Value;

           }

           return "";  

       }

   }

}


中间加了 ?  目的是  非贪婪匹配。


但是效果并不理想,效果如下:

111.png

按照最小匹配原则,原则上我们应该得到理想结果,但是却没有。


这是因为在正则的解释器中,对于最小匹配原则的理解为正向最小匹配,


而不是双向最小匹配。


左侧匹配后 定住左侧边界   直到找到右侧为止






我们换个思路:


中间包含在我们左侧的字符即可,




我们对代码进行改进:



Match match = Regex.Match(input, left + "(((?!" + left + ").)+?)" + right);


得到了我们想要的结果:

222.png

补充:





【零宽断言】


正则表达四一些字符可以匹配一句话的开始、结束(^ $)或者匹配一个单词的开始、结束(\b)。这些元字符只匹配一个位置,指定这个位置满足一定的条件,而不是匹配某些字符,因此,它们被成为 零宽断言。所谓零宽,指的是它们不与任何字符相匹配,而匹配一个位置;所谓断言,指的是一个判断。正则表达式中只有当断言为真时才会继续进行匹配。


在有些时候,我们精确的匹配一个位置,而不仅仅是句子或者单词,这就需要我们自己写出断言来进行匹配。下面是断言的语法:

断言语法


说明


(?=pattern)


前向肯定断言,匹配pattern前面的位置


(?!pattern)


前向否定断言,匹配后面不是pattern的位置


(?<=pattern)


后向肯定断言,匹配pattern后面的位置


(?<!pattern)


后向否定断言,匹配前面不是pattern的位置



更多参考:http://www.cnblogs.com/youring2/archive/2009/11/07/1597786.html

————————————————

版权声明:本文为CSDN博主「明明如月学长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/w605283073/article/details/48933895

相关文章
|
5天前
|
JavaScript 前端开发 Java
|
5天前
|
算法 测试技术 编译器
【算法 | 实验18】在字符矩阵中查找给定字符串的所有匹配项
题目描述 题目 在字符矩阵中查找给定字符串的所有匹配项 给定一个M×N字符矩阵,以及一个字符串S,找到在矩阵中所有可能的连续字符组成的S的次数。所谓的连续字符,是指一个字符可以和位于其上下左右,左上左下,右上右下8个方向的字符组成字符串。用回溯法求解。
40 1
|
5天前
正则表达前一个元素至少出现一次
正则表达前一个元素至少出现一次
47 4
|
6月前
|
存储 Java 网络安全
用正则表达式匹配3的任意倍数
正则表达式能匹配3的任意倍数?(注意是任意倍数) ,我曾经也很震惊,但确实可以。我5年多前练习正则表达式,在Regex Golf这个正则表达式测试网站上发现了这个题,当时完全没有任何头绪,于是我在知乎提问正则表达式如何匹配 3 的倍数 ,但是得到了好多知乎大佬的关注,也上了当天的热榜。 排名第一的答主已经给出了答案和思路,但这么多年来我一直都没看懂,最近学习编译原理,看到正则表达式和DFA,于是仔细研究了一下这个问题,并将问题扩展至匹配N的倍数,最后给出通用解法和代码。
18 0
【正则】匹配重复的单词
【正则】匹配重复的单词
139 0
正则匹配指定字符之间的内容,并替换(多个匹配替换)
var str="是吗@Test1:我觉得你说的很对@Test:学无止境"; var r=str.match(/@.*?:/ig); for (var index = 0; index < r.
2369 0
正则匹配起始字符串之间的文本
老是用到这个正则索性摸索了一下,试出了一个比较可靠的正则: public static string RegexReplaceStr(string regStr,string startStr,string endStr) { Regex regex = new Regex("(" + startStr + ").
825 0