一种傻瓜式生成 regex pattern 的设想
    2018-05-04 19:50:33 +08:00
  kongque2016
我有一个想法,能不能用常规编程语言来构建正则表达式,基本的实现方案是:
  1, 提供一个 Class,类的名字叫 Regex
  2, 提供一组基本的 API:
        Regex Any(string);				//字符群中的任意一个
        Regex None(string);				//字符群外的任意一个
        Regex Between(string);			//字符区间的任意一个
        Regex NotBetween(string);		//字符区外的任意一个
        Regex Regex(string);			//把 string 转换成 Regex 对象
        Regex Mustnot(Regex);			//negative look ahead
        ...
     这些 API 接受字符串参数,返回一个 Regex 对象.
     此外,Regex 对象本身也有 method,像:
     Regex Regex::repeat(min, max);          //重复 min 至 max 次
  3, Regex 对象之间是可以运算的(通过重载操作符), 运算的结果还是 Regex 对象.
     减号是取补集,像:
     Between("az") - Any("sdf")   是从 a-z 范围内挖掉 s,d,f 这三个字符.
     竖线|是取并集,加号+是连接, 感叹号!是取反,表示该集合之外的所有字符.
     
  4, 通过 Regex 对象,帮用户(一个程序员)生成它想要的 pattern 字符串.
  
  下面举几个例子,先来几个简单点儿的:
  匹配数字:	   Regex digit = Between("09")
  匹配字母:    Regex alpha = Between("az", "AZ")   //可以接受多个 range 参数
  匹配空白:    Regex  space = Any("\n\t\f\r\s")
  
  再来个稍微复杂些的,匹配 c 的变量名:
  Regex cword = 
  Mustnot( Between("09"))								//不能以数字开头
  + ( Between("09", "az", "AZ") | "_" ).repeat(1, 255);	//变量名长度小于 256
  
  其实能写的更简单点儿,因为之前已经定义过 digit, alpha 这些,可以当模板用:
  Regex cword = 
  Mustnot( digit ) 
  + (digit | alpha | "_").repeat(1, 255)
  
  前面说过 Regex 对象之间可以运算,所以上面有 digit | alpha | "_" 这样的写法. 只不过第三个运算对象"_"是 string 类型,我是嫌写成 Regex("_")麻烦,string 跟 Regex 对象运算时会自动的隐式转换为 Regex 对象.这是设计细节,就不多说了.
  
  
我觉得这种傻瓜式的构建 regex 的好处是,能把初学者从正则表达式的晦涩的文法里解放出来,有精力去体会 Regex 这项发明背后的基本思想.  即使这样写的稍慢一些,但总归能写出来,不至于要去网上求别人.
我现在正在着手写这个库,但总怀疑已经有人设计出来了,如果你知道的话,请一定赶紧告诉我!
最后,如果你有什么想法或建议,请不吝赐教.
    
    
    
    1 条回复
    
    
    
    
    
    这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
     https://www.v2ex.com/t/452213
      V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
      V2EX is a community of developers, designers and creative people.