千家信息网

怎样构造复杂的正则表达式

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍了怎样构造复杂的正则表达式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。避重就轻Snopo给出的文本是这样的:or a
千家信息网最后更新 2026年11月03日怎样构造复杂的正则表达式

这篇文章主要介绍了怎样构造复杂的正则表达式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。



避重就轻

Snopo给出的文本是这样的:or and name='zhangsan' and id=001 or age>20 or area='%renmin%' and like,问,如何提取其中正确的SQL查询语句。

简要分析可知,中间部分是合乎要求的,只是两端的有若干个like, or, and。构造能够解析合乎SQL语法的查询语句的正则表达式,应该是比较复杂的。可是,对于具体的问题,也可以更简单。上述的不良构的SQL语句,应该是使用程序自动生成的,它的两端会有一些不符合题意的文本。只要将这些文本去除就可以了。

于是,我写出了正则表达式:s/^(?:(?:or|and|like)\s*)+|\s*(?:(?:or|and|like)\s*)+$//mi;,这样就把多行字串首尾的like, or, and以及可能的空白字符全部去掉了,剩下的内容即为所求。

分而治之

答案发过去之后,Snopo显然不是很满意这种"偷懒"的办法。他继续问道,能否写出正则式,用来匹配合符SQL语法要求的条件查询语句?(只考虑where部分即可,不必写完整的select。)
的确,从快速解决问题的角度来说,只要能够行之有效地解决,用什么办法都可以;不过从学习知识的角度来说,不避重就轻,而是刨根问底,才是正途。既如此,就看一下如何使用正则,将该SQL查询语句解决掉。
最简单的查询语句,应该是真假判断,即 where 1; where True; where false,等等。 这样的语句使用正则式,直接/(?:-?\d+|True|False)/i。
稍复杂些的单条语句,可以是左右比较,即

name like 'zhang%', 或 age>25 ,或 work in ('it', 'hr', 'R&D')


。将其简单化,结构就变为A OP B。其中A代表变量,OP代表比较操作符,B代表值。

•A: 最简单的A,应该是\w+。考虑到实际情况,变量包含点号或脱字符,例如`table.salary`,可以记为/[\w.`]+/。这是比较笼统的细化。如果要求比较苛刻,还可以做到让脱字符同时在左右两边出现(条件判断)。
•OP: Where 常用的几种关系比较为:=, <>, >, <, >=, <=, Between, Like, in。使用简单的正则描述之,成为:/(?:[<>=]{1,2}|Between|Like|In)/i。
•B: B 的情况又可分为3种:变量,数字,字符串,列表。为简单起见,这里就不考虑算术表达式了。
变量的话,直接延用A的定义即可。不赘述。
数字:使用/\d+/来定义。不考虑小数和负数了。

字符串:包括单引号字串和双引号字串。中间可以包括被转义的引号。我写了一个符合这一要求的引号字串正则表达式,形如:/(['"])(?:\\['"]|[^\\1])*?\1/。不过,由于它只是庞大机器的一个零件,这样写的风险是极其大的。首先,它使用了反向引用;其次,该反向引用使用了全局的反向引用编号。我写了自动生成全局编号的函数,来解决这一问题。不过,这里谈细节是不是太深入了。应该先谈框架,再说细节才对。不应该一入手就陷进细节的汪洋大海。

◦列表:列表是形如(1, 3 , 4) 或 ("it", "hr", "r&d")之类的东东,它由简单变量以逗号相连,两边加上括号组成。列表的单项以I表示,它代表 数字|字符串。此时,列表就变为:/\(I(?:,I)*?\)/。它表示,左括号,一个I,一系列由逗号、I组成的其它列表项(0个或多个),右括号。简单起见没有考虑空白字符。
•至此,可以总结出单条语句的正则框架:S =~ /A OP B/i。S在此代表单条语句。
更为复杂的是多条语句,可以由单条语句组成,中间使用 and 或 or 连接。合理地构造单条语句,将其稳定地编制为多条语句,任务就完成了。

沿用上面的示例,以S代表单条语句,那么复合语句C就是 C =~ S(?:(?:or|and) S)*?/。至此,一个初具规模的条件语句解析器就诞生了。下面以python为例,一步一步实现出来。

Python实现
重申一句:虽然给出了实现,但是仍请注重思路,忽略代码。

#!/usr/bin/python# -*- coding: utf-8 -*-##author: rex#blog: http://iregex.org#filename test.py#created: 2010-08-06 17:12#generage quoted string;#including ' and " string#allow \' and \" insideindex=0def gen_quote_str():global indexindex+=1char=chr(96+index)return r"""(?P['"])(?:\\['"]|[^'"])*?(?P=quote_%s)"""% (char, char)#simple variabledef a():return r'[\w.`]+'#operatorsdef op():return r'(?:[<>=]{1,2}|Between|Like|In)'#list item within (,)#eg: 'a', 23, a.b, "asdfasdf\"aasdf"def item():return r"(?:%s|%s)" % (a(), gen_quote_str())#a complite list, like#eg: (23, 24, 44), ("regex", "is", "good")def items():return r"""\( \s*%s(?:,\s* %s)* \s*\)""" % (item(), item())#simple comparison#eg: a=15 , b>23def s():return r"""%s \s* %s \s* (?:\w+| %s | %s )""" % (a(), op(), gen_quote_str(), items())#complex comparison# name like 'zhang%' and age>23 and work in ("hr", "it", 'r&d')def c():return r"""(?ix) %s(?:\s*(?:and|or)\s*%s \s*)*""" % (s(), s())print "A:\t", a()print "OP:\t", op()print "ITEM:\t", item()print "ITEMS:\t", items()print "S:\t", s()print "C:\t", c()

该代码在我的机器上(Ubuntu 10.04, Python 2.6.5)运行的结果是:

A: [\w.`]+OP: (?:[<>=]{1,2}|Between|Like|In)ITEM: (?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_a))ITEMS: \( \s*(?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_b))(?:,\s* (?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_c)))* \s*\)S: [\w.`]+ \s* (?:[<>=]{1,2}|Between|Like|In) \s* (?:\w+| (?P['"])(?:\\['"]|[^'"])*?(?P=quote_d) | \( \s*(?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_e))(?:,\s* (?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_f)))* \s*\) )C:(?ix) [\w.`]+ \s* (?:[<>=]{1,2}|Between|Like|In) \s* (?:\w+| (?P['"])(?:\\['"]|[^'"])*?(?P=quote_g) | \( \s*(?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_h))(?:,\s* (?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_i)))* \s*\) )(?:\s*(?:and|or)\s*[\w.`]+ \s* (?:[<>=]{1,2}|Between|Like|In) \s* (?:\w+| (?P['"])(?:\\['"]|[^'"])*?(?P=quote_j) | \( \s*(?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_k))(?:,\s* (?:[\w.`]+|(?P['"])(?:\\['"]|[^'"])*?(?P=quote_l)))* \s*\) ) \s*)*

请看匹配效果图:


算术表达式
我记得刚才好像提到"为简单起见,这里就不考虑算术表达式了"。不过,解析算术表达式是个非常有趣的话题,只要是算法书,都会提及(中缀表达式转前缀表达式,诸如此类)。当然它也可以使用正则表达式来描述。
其主要思路是:

expr -> expr + term | expr - term | term term -> term * factor | term / factor | factor factor -> digit | ( expr )

以及代码:

#!/usr/bin/python # -*- coding: utf-8 -*- # #author: rex #blog: http://jb51.net #filename math.py #created: 2010-08-07 00:44 integer=r"\d+" factor=r"%s (?:\. %s)?" % (integer, integer) term= "%s(?: \s* [*/] \s* %s)* " % (factor, factor) expr= "(?x) %s(?: \s* [+-] \s* %s)* " % (term, term) print expr

看一下它的输出和匹配效果图:

感谢你能够认真阅读完这篇文章,希望小编分享的"怎样构造复杂的正则表达式"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

语句 表达式 正则 字符 代表 复杂 变量 查询 引号 算术 篇文章 代码 字符串 括号 数字 文本 条件 问题 避重就轻 两端 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳市人人互联网科技有限公司 上海卓越科技互联网 科技创新与互联网经济 互联网与科技发展 金融科技与互联网金融 以房互联网科技 华中科技大学互联网 唐信互联网科技 大连 互联网科技视频素材 互联网金融监管科技 北京三清互联网科技 青岛中康互联网医疗科技有限公司 剑昆互联网络科技有限公司临桂 花神(南京)互联网科技有限公司 宜昌元轩互联网科技有限公司 工业互联网展湾科技股份有限公司 马化腾互联网科技教学 互联网高科技绘画 互联网企业和网络科技有限公司 小牛互联网科技有限公司地址 中国互联网科技工作委员会毛军 中资互联网科技 麻工互联网科技 互联网科技公司官网 壕鑫互联网络科技 卓越科技互联网 招聘 互联网科技项目计划书材料类 工业互联网山东科技大学 银行科技岗属于互联网吗 工业互联网科技创业
0