标题: [问题求助] chatgpt写的PowerShell正则平衡组示例改错 [打印本页]
作者: 小白龙 时间: 2023-4-11 13:32 标题: chatgpt写的PowerShell正则平衡组示例改错
刚刚让chatgpt写几个平衡组示例, 但是执行结果都是错的, 求路过大佬改正
也第一次看到正则表达式可以多行表示, 而且行尾还能加注释, C#不能这样玩吧- $pattern = @"
- \(
- (?> # 开始一个平衡组
- [^()]+ # 匹配除了括号以外的任意字符
- | # 或者
- (?<paren>\() # 匹配左圆括号并将其压入名为paren的平衡组中
- | # 或者
- (?<-paren>\)) # 匹配右圆括号并将其弹出名为paren的平衡组中
- )* # 重复上述步骤多次
- (?(paren)(?!)) # 如果paren平衡组不为空,则匹配失败
- \)
- "@
-
- $text = "This is (a (test) string) with (nested (parentheses))."
- $matches = [regex]::Matches($text, $pattern)
- foreach ($match in $matches) {
- Write-Host $match.Value
- }
复制代码
作者: idwma 时间: 2023-4-11 19:08
直接告诉chatgpt结果错了他会帮你改过来的呀,现在ai进化速度很快现在错了过一会可能就对了
作者: 小白龙 时间: 2023-4-11 19:20
回复 2# idwma
我让他改了N次, 都改不对
作者: idwma 时间: 2023-4-11 19:27
这个例子看着没问题呀,什么样的结果才是对的?
作者: 小白龙 时间: 2023-4-11 19:31
本帖最后由 小白龙 于 2023-4-11 19:32 编辑
回复 4# idwma
输出结果为空, 什么都没有输出, 应该输出所有括号
作者: idwma 时间: 2023-4-11 19:57
本帖最后由 idwma 于 2023-4-11 19:59 编辑
回复 5# 小白龙
确实是有结果的,是不是你的powershell版本不是最新的
(a (test) string)
(nested (parentheses))
作者: 小白龙 时间: 2023-4-11 20:04
回复 6# idwma
我用的是win7 ps5.1
作者: idwma 时间: 2023-4-11 20:07
回复 7# 小白龙
5.1不是最新的,告诉chatgpt用ps5.1来举例试试
作者: xczxczxcz 时间: 2023-4-11 20:09
俺只知道目前地球上只有人类大脑和其它生物的才是智能。其它都是复读机,炒作=>股票
gpt 是错的- $pattern = @"
- (?x)\(
- ( # 开始一个平衡组
- (?>[^()]*) # 匹配除了括号以外的任意字符 固化不回溯,其实多余 因[^()]*本身最多回溯一个字符,
- | # 分支
- (?<o>\() # 匹配左圆括号并将其压入名为o的栈
- | # 分支
- (?<-o>\)) # 匹配右圆括号并将其弹出名为o的栈
- )* # 重复上述步骤多次
- (?(o)(?!)) # 如果o平衡组不为空,则匹配失败
- \)
- "@
- [regex]::Matches($text, $pattern).Value
复制代码
- [regex]::Matches($text, "(?x)\( ( [^()]* | (?<o>\() | (?<-o>\)) )*(?(o)(?!)) \)").Value
复制代码
作者: xczxczxcz 时间: 2023-4-11 20:18
再次声明: ? 不参与匹配, + * 均匹配从匹配点起的后面的全部(不是网上说的匹配0个1个多个)然后回溯,结果写入 GROUPS[0]中。
作者: 小白龙 时间: 2023-4-11 20:19
回复 8# idwma
哎, 问了七八轮了, 还没有答对, 太垃圾了
作者: 小白龙 时间: 2023-4-11 20:29
回复 10# xczxczxcz
大佬, 牛X啊, 对正则理解太深刻了, 有什么精华的正则教程链接给推荐一下吗
作者: idwma 时间: 2023-4-11 20:29
毕竟是人工智能嘛,还是离不开人,按x大的加上忽略转义空白(?x)其实也是有结果的
作者: 小白龙 时间: 2023-4-11 20:45
回复 13# idwma
什么意思, x大的那两个正则都可以直接出结果的, 在ps5.1
作者: idwma 时间: 2023-4-11 20:50
回复 14# 小白龙
你看像这样,gpt给的没忽略非转义空白,加上(?x)就好了- $pattern = @"
- (?x)\(
- (?> # 开始一个平衡组
- [^()]+ # 匹配除了括号以外的任意字符
- | # 或者
- (?<paren>\() # 匹配左圆括号并将其压入名为paren的平衡组中
- | # 或者
- (?<-paren>\)) # 匹配右圆括号并将其弹出名为paren的平衡组中
- )* # 重复上述步骤多次
- (?(paren)(?!)) # 如果paren平衡组不为空,则匹配失败
- \)
- "@
复制代码
作者: 小白龙 时间: 2023-4-11 20:52
回复 15# idwma
多谢, 明白了
GPT的答案做个参考就行了, 关键还得自己要懂
作者: 小白龙 时间: 2023-4-12 06:54
回复 15# idwma
大佬, 像这种能带注释的正则式有点实用, 以后想改的时候, 一目了然, 但是如果表达式中需要空格时怎么办? \s 虽然包含空格, 但还包含其它几个空字符
作者: idwma 时间: 2023-4-12 13:44
本帖最后由 idwma 于 2023-4-12 13:45 编辑
回复 17# 小白龙
[ ]
不想问ai了搜一搜手册也是很好的方式呀- https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expression-options#ignore-white-space
复制代码
作者: WHY 时间: 2023-6-5 22:01
回复 9# xczxczxcz
这里的“固化分组”并非多余,而是必须。
'([^()]+)*' 正则这样写,如果匹配失败,很容易引起 "灾难性回溯",或称 "无休止回溯"。
https://blog.csdn.net/weixin_40619578/article/details/127287867
作者: xczxczxcz 时间: 2023-6-6 10:35
回复 19# WHY
本来不想登陆的,但看了你写提示那个,感觉还是说两句的好。 请问您可以一个字符一个字符的 检索出 ([^()]+)* 的匹配和回溯教程吗? [^()]+ ,[^()]* 它们的的真正含意是什么吗? 还有你给的链接,那种破三烂的正则(看起来不像NET正则)就不要给链接(鄙视csdn,虽然俺开始也是看这的,但到后来发现里面的文章各种垃圾, 然后屏蔽),会降低您的智力。链接中的 (\.*)* 你想过这是什么破玩意吗。你可以想下这个回溯过程,指数级增长(还是那句话对正则回溯不清楚就不要写.* .+ .*? .+?之类), 还有 你确定 [^()]* [^()]+ 有回溯?可以自己实验下。不要拿网上那种垃圾文章还有阿三的微软例子来证明自己是对的。
您应该知道 visual studio code 中最烂的应用是什么。 不夸张的说是powershell;vscode对py js java等支持的好得不得了,但对PS支持就是一个烂字。
作者: xczxczxcz 时间: 2023-6-6 10:43
([^()]+)* 和 [^()]+ 是两上不同的东西
作者: WHY 时间: 2023-6-6 11:39
回复 20# xczxczxcz
好好看看"精通正则表达式第三版"第6章,第225页开始就是说的这个问题: "过渡回溯"。
.NET和其它如JAVA、PHP等等正则,都是基于传统NFA型的,我从来不认为这个很好,那个很垃圾。
作者: xczxczxcz 时间: 2023-6-6 11:44
本帖最后由 xczxczxcz 于 2023-6-6 12:07 编辑
记得以前一直不知道正则到底是如何匹配,它每一步在做什么,因为不清不楚就不知道如何正确的写正则。然后,脑一热,准备写内存跟踪(因网上的教程不可靠,天下一大抄),架子都写了,然后就发现在一个网上的一个角落有位古董级大佬发有一篇日志,记录了他追踪内存的数据,他曾经也是不知正则的所以然就写了内存跟踪,看正则到底在内存中写了什么数据。然后的然后就再也不看网上的正则教程了,因为它妈的除了烂还是烂。现在就不知道发明正则的大佬的匹配和回溯过程是不是我们现在理解的一样。
* + 共同的东西是 遇到与条件相符,匹配立即停止,若匹配完,有结果,+ *都返回true; 没结果 * 返回
true; +返回false; ?反向回溯,
因从没写过教程,感觉写的很乱,有些地方条件没写上有可能导致说法不成立;比如 [^\w]*, 这是不回溯的;但 [^\w]*a 这是回溯的
作者: WHY 时间: 2023-6-6 21:48
本帖最后由 WHY 于 2023-6-11 20:59 编辑
可能是我没有表达清楚什么意思,也可能是我高估了有些人的理解能力。
顶楼的正则,抛开所谓的"平衡组",可以这样写:
'\((?>[^()]+|\(|\))*\)'
如果取消固化分组,可以这样写:
'\(([^()]+|\(|\))*\)'
这与《精通正则表达式(第三版)》第225页的例子:"(\\.|[^"\\]+)*" 如出一辙。
第268页 "使用固化分组和占有优先量词" 已经把引起灾难性回溯的原因及解决办法说得很清楚了。
什么时候匹配失败会引起灾难性回溯?
比如:- '(abcdefghijklmnopqrstuvwxyz' -match '\(([^()]+|\(|\))*\)'
复制代码
当然,如果认为《精通正则表达式(第三版)》很烂,或者认为这本书已经过时,那我无话可说。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |