Board logo

标题: [文本处理] 用findstr模拟正则表达式元素区间量词的方法 [打印本页]

作者: qixiaobin0715    时间: 2021-1-15 09:28     标题: 用findstr模拟正则表达式元素区间量词的方法

虽然有人并不认可findstr,但有时还能解决一些问题的。
学习批处理前,曾经接触过正则表达式。后来发现findstr可以使用简单的正则,但是其功能大大缩水。
写批处理有时过滤字符串需要用到类似正则中表达前面元素的数量词(类似正则中的?、{min,max}),就会出现局限性,只能退而求其次,进行非精确匹配。
不过最近想到了办法来模拟正则区间量词的表达,独乐乐不如众乐乐,现分享给大家,有不足的地方希望各位大佬批评指正。
比如我要显示出a.txt中有1-3个纯数字构成的所有行。用正则表达式匹配简单明了,应当是:^\d{1,3}$或^[0-9]{1,3}$;用findstr中的所谓一般表达式(微软是这么翻译的)就要麻烦多了。
findstr中量词只有*可用(相当于{0,}),连?都不支持(相当于{0,1})。所以得想其他的方法。有两个思路可以考虑。
1.采用findstr的多字符搜索的方法:
findstr /r "^[0-9]$ ^[0-9][0-9]$ ^[0-9][0-9][0-9]$" a.txt
多个搜索字符整体要用双引号括起来;
各字符串之间用一个空格分隔;
各字符串首尾各添加行首行尾标记^$;
各个单字符串中间不能有空格;
三个搜索字符串分别对应1/2/3个纯数字构成的行;
2.采用findstr两次过滤的方法:
findstr /r "^[0-9][0-9]*$" a.txt|findstr /r /v "^[0-9][0-9][0-9][0-9][0-9]*$"
两个搜索字符串首尾都要添加行首行尾标记^$;
第一个findstr搜索目标是a.txt,并根据搜索字符串过滤内容;
第二个findstr是以第一个findstr过滤的内容为目标,并再次过滤;
第一个搜索字符串将非纯数字的行过滤掉,留下了纯数字的行;
第二个搜索字符串将多于三个数字的纯数字行过滤掉,留下的自然是1-3个纯数字的行;
/v表示排除获得匹配的行;
上面例子是为了演示方便,使用了纯数字行匹配的方法,其它情况的匹配可以自己发挥。
比如要匹配在字符@和#之间有2-4个数字的行。
正则表达式:^.*@\d{2,4}#.*$
findstr多字符:findstr /r "@[0-9][0-9]# @[0-9][0-9][0-9]# @[0-9][0-9][0-9][0-9]#" a.txt
findstr过滤法:findstr /r "@[0-9][0-9][0-9]*#" a.txt|findstr /r /v "@[0-9][0-9][0-9][0-9][0-9][0-9]*#"
还可以模拟正则中的量词“?”。
正则表达式:^.*@\d?#.*$
findstr多字符:findstr /r "@# @[0-9]#" a.txt
findstr过滤法:findstr /r "@[0-9]*#" a.txt|findstr /r /v "@[0-9][0-9][0-9]*#"
需要说明的是在findstr中模拟的只是对单个字符元素的匹配,比如像匹配这样的ababababab字符第一种勉强应付,而第二种就望尘莫及了,正则可轻松匹配:(ab){min,max}。正则表达式功能强大,像这种简单的嵌套正则(a{2,4}b){1,2},findstr就很难表达了。
作者: Batcher    时间: 2021-1-15 09:48

回复 1# qixiaobin0715


第二种方法管道后面的可以简化成这样吧:
findstr /r "^[0-9][0-9]*$" 1.txt|findstr /v "[0-9][0-9][0-9][0-9]"
作者: qixiaobin0715    时间: 2021-1-15 09:56

回复 2# Batcher
对对!!!但为了和后面的例子保持一致性和可读性,就保留了前后的^$。
作者: qixiaobin0715    时间: 2021-1-15 09:58

后面的例子中的@#不能省略。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2