写作绅士,读作丧尸 X岛揭示板
顺猴者昌 逆猴者亡 首页版规 |用户系统 |移动客户端下载 | 丧尸路标 | | 常用图串及路标 | 请关注 官方公众号:【X岛揭示板】 官方微博: 【@X岛极速版】| 人,是会思考的芦苇
常用串:·豆知识·跑团板聊天室·公告汇总串·X岛路标

No.56193538 - 无标题 - 技术宅


回应模式
No.56193538
名 称
E-mail
标题
颜文字
正文
附加图片
•程序语言、压制投稿、视频制作以及各计算机领域的技术问题
•我觉得还是CSDN靠谱一点
•本版发文间隔为15秒。

无标题 无名氏 2023-03-14(二)17:58:36 ID:c4j7i5U [举报] [订阅] [只看PO] No.56193538 [回应] 管理
正则表达式怎么才能排除引号内的匹配( ゚∀。)

比如:

从hello, world!中匹配到world
但从hello, "world!"中什么也不要匹配到
Tips 无名氏 2099-01-01 00:00:01 ID:Tips超级公民 [举报] No.9999999 管理
发芽的洪! ︵ᵟຶ
( `д´)ジ
无标题 无名氏 2023-03-14(二)19:42:58 ID:4WVuFwF [举报] No.56195724 管理
设置开头结尾不为引号
无标题 无名氏 2023-03-14(二)21:38:51 ID:c4j7i5U (PO主) [举报] No.56198512 管理
>>No.56195724
那像是"world" world "world"这样的我想让它能匹配出中间的world怎么办
无标题 无名氏 2023-03-14(二)22:09:59 ID:1b296le [举报] No.56199234 管理
>>No.56198512
这种情况如果字符串太复杂,正则是做不到的,你得自己写一个parser
无标题 无名氏 2023-03-14(二)23:44:33 ID:T4A7oFc [举报] No.56201643 管理
先用其他方式把你不想被匹配到的部分去掉,再来用正则
无标题 无名氏 2023-03-15(三)00:31:06 ID:T4A7oFc [举报] No.56202553 管理
>>No.56201643
或者多次运用正则,先匹配到不想要的部分,去掉它们,然后在余下的部分再次运用正则,取得想要的部分(`・ω・)
收起 查看大图 向左旋转 向右旋转
无标题 无名氏 2023-03-15(三)01:41:12 ID:Qz0gzw5 [举报] No.56203296 管理
这种情况可以使用正则表达式的先行和后行断言(lookahead & lookbehind)
比如匹配字符串中不以引号开头或结尾的特定字符串,可以表示成:
(?<!['"])world(?!['"])
这样将会只匹配前一个字符和后一个字符均不是单引号或双引号的world
效果如图:
无标题 无名氏 2023-03-15(三)09:41:10 ID:q6tmA7C [举报] No.56205909 管理
>>No.56203296
同意,用断言的方法,不过正则教程基本都会跳过断言,得自己去搜,不晓得为什么
无标题 无名氏 2023-03-15(三)17:25:52 ID:THqu6kc [举报] No.56214528 管理
因为断言写得不好会变成回溯地狱,面向新手的教程就懒得教了
无标题 无名氏 2023-03-15(三)17:26:35 ID:THqu6kc [举报] No.56214541 管理
而且断言这个功能较新,不所有正则引擎支持
无标题 无名氏 2023-03-21(二)13:13:34 ID:ALwo5GV [举报] No.56335340 管理
要不先把引号和引号内的内容先dd掉
无标题 无名氏 2023-03-21(二)21:58:42 ID:Yo6DWBp [举报] No.56345049 管理
可以使用负向零宽断言来实现排除引号内的匹配。具体来说,可以使用以下正则表达式:```
(?<!["'])\b\w+\b(?!(["'])[^"']*?\1)
```

这个正则表达式的含义是:

- `(?<!["'])`:负向零宽断言,表示前面不能有单引号或双引号。
- `\b\w+\b`:匹配一个单词,即由字母、数字或下划线组成的连续字符。
- `(?!(["'])[^"']*?\1)`:负向零宽断言,表示后面不能有成对的单引号或双引号。

这个正则表达式的作用是,先匹配一个单词,然后判断这个单词前面和后面是否有引号,如果有引号则不匹配,否则匹配。注意,这个正则表达式只能排除成对的引号,如果有单独的引号则无法排除。
无标题 无名氏 2023-03-22(三)23:46:32 ID:U7fbEhK [举报] No.56367018 管理
那就让正则不要匹配引号就好了
收起 查看大图 向左旋转 向右旋转
无标题 无名氏 2023-04-04(二)12:03:10 ID:LDnxzZz [举报] No.56611825 管理
(?=[^"])world(?=[^"])
无标题 无名氏 2023-04-04(二)12:09:49 ID:ip916kB [举报] No.56611947 管理
如果输入里只有引号是具有特殊意义的分隔符,直接先匹配一次把所有引号里的内容删了得了
无标题 无名氏 2023-04-04(二)19:45:08 ID:e0JGM8m [举报] No.56619649 管理
这个问题有点麻烦,但正则表达式确实是可以一次做到的。
留意到引号不分左右,所以不会嵌套,如果要取出引号外的成分,可以先将原字符串对引号做一次split,然后取出单数(一起,如零起则双数)下标的子字符串。
按照这个思路,可以直接判断模式前后各有多少引号,仅当均有双数个引号时留下,此时模式在引号之外。事实上这就是判断平面上一点是否位于一多边形之内的射线法的思路。
考虑以下例子:
```
"hello hello" "hello" hello "hello" hello hello "hello"
```
此时引号外的`hello`只有第四、六、七个(一起),其他的都在引号之内,不要。要恰好找到它们,对应的完整正则表达式是:
```
(?<=([^"]*"[^"]*")*[^"]*$)hello(?=([^"]*"[^"]*")*[^"]*$)
```
但这里有个危险:在负向零宽断言中出现了不定量词。有的环境会将以上式子判断为不合法。如果能够保证整句的引号匹配(即总共有双数个),那么可以只留下后面一半(因为后面有双数个引号等价于前面也有双数个),即
```
hello(?=([^"]*"[^"]*")*[^"]*$)
```
无标题 无名氏 2023-04-04(二)19:50:04 ID:e0JGM8m [举报] No.56619748 管理
>>No.56619649
修正:完整的式子应该是
```
(?<=^([^"]*"[^"]*")*[^"]*)hello(?=([^"]*"[^"]*")*[^"]*$)
```
因为我用的环境不接受这种用法,所以没测试( ゚∀。)

UP主: