我的正则表达式之“Hello,World!”

本文详细介绍了使用正则表达式验证特定格式输入的过程,包括如何编写正则表达式以匹配特定模式,以及如何通过JavaScript进行实时验证。
和正则表达式纠缠了两天,总算弄明白了关于正则表达式的大约2%内容,写出了我自己的第一个正则表达式(在JAVASCRIPT里叫做RegExp)。 主要是为了能在网页里验证文本框的输入,限制为必须如q+n+b+k+x这样的形式。 规则为: 1、不允许输入除了“qnbkx+”这六个字符以外的其他字符; 2、字母之间必须用+连接,长度不限但字母不能重复(连续或者非连续重复都不允许); 3、+可以重复但不允许以+开头; 4、+不允许连续重复如+++。 合法的输入示例如下: q+n、q、q+n+x、n+q+k+、x+ 非法的输入示例如下: +、+q(这两个都是以+开头) n+n、n+kk、q+n+k+n(n重复了,k重复了,n重复了) q++n(两个+连续重复) qk(字母之间必须用+连接) 就为了解决这个输入验证,我花了两个整天学正则表达式!! 在百度知道里也问了这个问题,一直没人回复。 后来还是自己解决,在文本框的onkeyup里用了个很笨的办法:每输入一个字就检查一遍上面那几个规则,把不符合规则的字符用replace替换掉。具体代码如下: //去掉开头的+和全部其他字符,去掉连续的字符 var thevalue=thetext.value.replace(/(^/+)|([^qnbkx/+])|([qnbkx]{2,})/g,''); //去掉间隔其他字符重复出现的q、n、b、k、x var tmpstr var firstpos firstpos=thevalue.search(/([qnbkx]).*/1/g); if (firstpos>-1){ tmpstr=thevalue.slice(0,firstpos) thevalue=tmpstr+thevalue.slice(firstpos+1,thevalue.length) } thevalue=thevalue.replace(/[/+]+/g,'+');//连续的多个+替换成一个 thevalue=thevalue.replace(/^/+/g,'');//再次检查和去掉开头的+ thetext.value=thevalue; 看上去有点晕吧?我自己也晕,写的代码运行正常检测通过,但是过段时间再来看代码自己都看不懂了。简单解释一下: 1、用“/”和“/”把正则表达式包含进去,后面跟个g代表全局匹配。 2、(^/+)|([^qnbkx/+])|([qnbkx]{2,})这段里用两个“|”把三个匹配项隔开,“|”表示逻辑或,跟or一个意思。 3、^和$分别代表字串开头和结尾。但是^也可以表示逻辑反,如^qnbkx/+就表示除了qnbkx+这几个字符以外的一切字符。其中的/+代表字符+(因为单独的+有别的含义)。 4、{2,}表示它前面的东西要重复至少2次或者更多次。 5、firstpos=thevalue.search(/([qnbkx]).*/1/g)这句是要找到字符串中重复两次的字母,并且把其中第一次出现的位置记录下来,然后把找到的重复字母的第一个去掉: if (firstpos>-1){//如果找到了重复字母。例如q+k+n+b+n+x,n重复了 tmpstr=thevalue.slice(0,firstpos);//把字串中第一个重复字母前的那部分保存到tmpstr,如q+k+ thevalue=tmpstr+thevalue.slice(firstpos+1,thevalue.length)//把重复字母第一次出现之后的部分+b+n+x和前面的连起来 } //结果为q+k++b+n+x,虽然把第一个n去掉了,但是形成了两个连续的+,没关系,后面还有代码thevalue=thevalue.replace(/[/+]+/g,'+')把连续的多个+换成一个。 由于是在onkeyup里执行这段代码,所以不用担心会出现一个字母重复3次以上,就用不着用while连续search和slice了。 (第二天我发现我这想法太天真了,如果存心构造个重复多次的字串粘贴进去,我的程序就乱套了,还是必须用while循环检测,把所有重复都去掉。不然,如果想偷懒的话……所谓的BUG和程序漏洞就是因此而产生的,大名鼎鼎而得意的hacker们也因此而得以存在……) 昨天晚上临睡前又想到可以用个正则表达式在提交FORM的时候用ASP再检查一遍最终的输入是否匹配: /^[qnbkx]{1}(/+[qnbkx]?)*(?!/+)$/ 不过不能检查出间隔重复的字母。除非再用另外一个正则表达式。 今天在百度知道里看到了有人回答了可以用/^([qnbkx]/+)*([qnbkx]|){1}$/来匹配,比我上面想到的那个简洁一些,但还是一样不能同时解决字母间隔重复的问题。
<think>我们正在讨论正则表达式中的操作符,特别是~和!~*的区别。根据用户提供的引用,引用[3]提到了"~="用于替换操作,但用户问题中的~和!~*可能是在匹配上下文中使用的操作符,尤其是在某些特定的正则表达式引擎(如PostgreSQL的POSIX正则表达式)中。注意:在PostgreSQL的正则表达式中:~表示区分大小写的正则表达式匹配。!~表示不匹配区分大小写的正则表达式。~*表示不区分大小写的正则表达式匹配。!~*表示不匹配不区分大小写的正则表达式。因此,用户问的!~*就是“不匹配不区分大小写的正则表达式”操作符。但是,用户提供的引用中并没有直接提到这些操作符,所以我们需要根据已知的正则表达式知识进行解释。让我们整理一下:操作符:~:匹配,区分大小写(例如'abc'~'a'为真,但'abc'~'A'为假)~*:匹配,不区分大小写(例如'abc'~*'A'为真)!~:不匹配,区分大小写(例如'abc'!~'A'为真,因为区分大小写时'A'不匹配'abc')!~*:不匹配,不区分大小写(例如'abc'!~*'d'为真,因为不区分大小写时,'d'也不在'abc'中;但'abc'!~*'A'为假,因为不区分大小写时'A'匹配'a')因此,区别在于:~和!~是区分大小写的匹配操作符。~*和!~*是不区分大小写的匹配操作符。示例说明:1.使用~(区分大小写匹配):示例:判断字符串'HelloWorld'是否包含'world'(小写)'HelloWorld'~'world'->假(因为区分大小写,'world'中的'w'是小写,而原字符串中是'W'大写)2.使用~*(不区分大小写匹配):示例:判断字符串'HelloWorld'是否包含'world'(小写)'HelloWorld'~*'world'->真(不区分大小写,所以'world'匹配'World')3.使用!~(区分大小写不匹配):示例:判断字符串'HelloWorld'是否不包含'world'(小写)'HelloWorld'!~'world'->真(因为区分大小写,所以确实不包含小写的'world')4.使用!~*(不区分大小写不匹配):示例:判断字符串'HelloWorld'是否不包含'abc'(任意大小写)'HelloWorld'!~*'abc'->真(因为字符串中确实没有'abc'或'ABC'等)另一个示例:判断字符串'HelloWorld'是否不包含'world'(不区分大小写)'HelloWorld'!~*'world'->假(因为不区分大小写时,'world'匹配'World',所以是匹配的,那么不匹配就是假)注意:这些操作符在PostgreSQL中常用,但在其他正则表达式实现中可能不同。例如,在Perl或Python中,我们通常使用=~或re.search()等,并且通过标志控制大小写。用户引用中提到了Qt中的正则表达式(引用[1])和Python(引用[4]),但用户的问题似乎更倾向于这种操作符形式,因此我们假设是在类似PostgreSQL的上下文中。如果用户是在其他环境(如Python)中,那么这些操作符可能并不直接存在,而是通过函数参数(如re.IGNORECASE)来实现。因此,我们需要根据上下文环境来确定。但用户问题中明确提到了~和!~*,所以我们按照PostgreSQL的风格解释。总结:~:区分大小写的正则表达式匹配!~*:不区分大小写的正则表达式匹配(即:当字符串不匹配给定的正则表达式(不区分大小写)时返回真)示例:假设有一个表users,其中有一列username。查询username包含'john'(区分大小写)的所有用户:SELECT*FROMusersWHEREusername~'john';查询username不包含'john'(不区分大小写)的所有用户(即:即使出现'John'、'JOHN'也不包含):SELECT*FROMusersWHEREusername!~*'john';注意:在第二个查询中,如果username是'John',那么!~*'john'将返回假,因为'John'不区分大小写匹配'john',所以它不在结果中。而如果使用!~'john'(区分大小写),那么'John'就不会被匹配(因为区分大小写,'John'中的'J'是大写),所以会返回真,即该记录会被选中。因此,区别在于大小写敏感性和是否取反。根据用户要求,我们生成相关问题:1.在哪些编程语言或数据库系统中支持~和!~*这样的正则表达式操作符?2.除了~和!~*,还有哪些常用的正则表达式操作符?3.如何在Python中实现类似~和!~*的功能?4.正则表达式中大小写不敏感匹配的其他实现方式有哪些?注意:用户提供的引用中,引用[3]提到了一个替换操作,其中使用了~=和分隔符,这与匹配操作符不同。所以我们需要区分替换和匹配。因此,在回答中,我们要明确指出用户问题中的操作符是用于匹配的,而不是替换。</think>### 正则表达式中 `~` 和 `!~*` 操作符的区别及示例说明 #### **核心区别** | 操作符 | 功能描述 | 大小写敏感 | 匹配逻辑 | |--------|------------------------------|------------|------------| | `~` | **匹配**指定正则模式 | 敏感 | 返回真 | | `!~*` | **不匹配**指定正则模式 | 不敏感 | 返回真 | > **关键差异**: > - `~` 是**基础匹配**(区分大小写),`!~*` 是**不敏感的非匹配**(不区分大小写 + 取反)。 > - `!~*` = `!`(逻辑非) + `~*`(不敏感匹配)。 --- #### **示例详解** 假设文本为 `"Regex is powerful"`: 1. **`~` 操作符(区分大小写匹配)** ```sql -- PostgreSQL 示例 SELECT 'Regex is powerful' ~ 'power'; -- 真(匹配成功) SELECT 'Regex is powerful' ~ 'Power'; -- 假(大小写不匹配) ``` - 只匹配小写 `power`,大写 `Power` 不匹配。 2. **`!~*` 操作符(不区分大小写的不匹配)** ```sql -- PostgreSQL 示例 SELECT 'Regex is powerful' !~* 'weak'; -- 真(文本中无 weak/WEAK/WeAk) SELECT 'Regex is powerful' !~* 'POWER'; -- 假(不区分大小写时匹配 POWER/power) ``` - 检查文本**是否不包含**指定模式(忽略大小写)。 --- #### **应用场景** 1. **数据清洗** ```sql -- 筛选不含 "error" 或 "ERROR" 的日志 SELECT log FROM logs WHERE log !~* 'error'; ``` 2. **输入验证** ```python # Python 模拟 !~*:验证字符串不含数字(不区分大小写) import re text = "HelloWorld" if not re.search(r'\d', text, re.IGNORECASE): print("通过验证") # 输出结果 ``` 3. **文件过滤** ```bash # 查找所有非图片文件(忽略扩展名大小写) ls | grep -v -i '\.(png|jpg|gif)$' ``` --- #### **常见误区** - **`~*` vs `!~*`**: `~*` 是不敏感匹配(如 `'A' ~* 'a'` 为真),`!~*` 是其取反。 - **语言差异**: `~`/`!~*` 在 **PostgreSQL、Perl** 中直接支持,其他语言需用函数组合实现(如 Python 的 `re.search` + 标志位)。 > 参考:Qt 中类似功能可通过 `QRegularExpression` 的 `caseInsensitive` 选项实现[^1],Python 通过 `re.IGNORECASE` 标志[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值