标题: [问题求助] PowerShell正则平衡组获取{}内多行文本 [打印本页]
作者: 小白龙 时间: 2023-5-26 17:06 标题: PowerShell正则平衡组获取{}内多行文本
下面要处理的字符串变量$s 内有两个类,分别是 xx类 和 zz类, 每个类下都有 Main函数 和 hello函数
我想获取所有Main函数体的文本,下面的代码执行后, 始终只能取两行, gpt也被我搞晕了, 几十回合都在重复一个代码, 哎
在下对平衡组还是一知半解, 求路过大佬帮助
最好能写成一个函数, 函数名 getFuncText 有两个参数, 第1个函数是函数名, 第二个函数是 类名
用法1: 如果只有第1个参数 函数名 没有第2个参数 类名 那就把下面所有类中的 该函数内的文本全输出
getFuncText "Main"
用法2: 如果既有第1个参数 函数名 又有第2个参数 类名 那就只把该类下的 该函数内的文本输出
getFuncText "Main" "xx"
感觉描述是很清楚的, GPT确理解不了, 可能太难了
另外, 类前面的修饰符会有多种情况: 下面是idwma大佬写的平衡组表达示, 供参考:
$s -match '(?<a>\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>class\s+cs\s*(\([^)]*\))*\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
$regex='(?<a>\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>(abc|cd)\s*\([^)]*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'- $s = @'
- using System;
-
- public class xx
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"}{{";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
-
- public class zz
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"{{}";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
- '@
-
- $regex = '(?<=Main\s*\(\)\s*\{)(?<BODY>(?:[^{}]+|(?<OPEN>\{)|(?<-OPEN>\}))*)(?(OPEN)(?!))(?=\})'
-
- if ($s -match $regex)
- {
- $match = $Matches['BODY']
- Write-Output $match
- }
复制代码
作者: idwma 时间: 2023-5-26 18:46
本帖最后由 idwma 于 2023-5-26 18:55 编辑
- function getFuncText($a,$b){
- if(!$b){$b='\S+'}
- $r='(?<a>\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>'+$b+'\s*(\([^)]*\))*\s*\{\n(?>(?<d>\s*(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>'+$a+'\s*(\([^)]*\))*\s*\{(?>[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\n|.)*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}))|[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\n|.)*?\*/|[\x22\x27](\n|.)*?[\x22\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
- [regex]::Matches($s, $r).groups|?{$_.name -eq 'd'}|%{$_.captures.value}
- }
复制代码
作者: 小白龙 时间: 2023-5-26 18:58
回复 2# idwma
多谢大佬, 试了一下, 没有输出- $s = @'
- using System;
-
- public class xx
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"}{{";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
-
- public class zz
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"{{}";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
- '@
-
- function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $r = '(?<a>\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $b + '\s*(\([^)]*\))*\s*\{(?>(?<d>(\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $a + '\s*(\([^)]*\))*\s*\{(?>[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\n|.)*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}))|[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\n|.)*?\*/|[\x22\x27](\n|.)*?[\x22\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
-
- getFuncText -a "Main"
- "--------------------------"
- getFuncText -a "Main" -b "zz"
复制代码
作者: idwma 时间: 2023-5-26 19:04
回复 3# 小白龙
测过是有的
作者: 小白龙 时间: 2023-5-26 19:09
回复 4# idwma
我的没有任何输出, window7 x64 powershll 5.1
作者: idwma 时间: 2023-5-26 19:34
回复 5# 小白龙
用win7 5.1测了也是有的
作者: 小白龙 时间: 2023-5-26 20:03
回复 6# idwma
这是我测试的文件
https://t.wss.ink/f/bax41qzzn9f 复制链接到浏览器打开
作者: 小白龙 时间: 2023-5-26 20:50
回复 6# idwma
奇怪, 在另一台电脑上也不行,
作者: idwma 时间: 2023-5-26 21:06
- function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $r = '(?<a>\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $b + '\s*(\([^)]*\))*\s*\{(?>(?<d>(\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $a + '\s*(\([^)]*\))*\s*\{(?>[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}))|[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22\x27](\r?\n|.)*?[\x22\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
复制代码
作者: 小白龙 时间: 2023-5-26 21:15
回复 9# idwma
现在输出如下, 但是我只需要红色字部分
public static void Main()
{
string s = "xzc abc(s \"(abc)\")); dfg()";
string p = @"}";
string q = @"}{{";
string[] result = matches(s, p);
}
public static void Main()
{
string s = "xzc abc(s \"(abc)\")); dfg()";
string p = @"}";
string q = @"{{}";
string[] result = matches(s, p);
}
--------------------------
public static void Main()
{
string s = "xzc abc(s \"(abc)\")); dfg()";
string p = @"}";
string q = @"{{}";
string[] result = matches(s, p);
}- $s = @'
- using System;
-
- public class xx
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"}{{";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
-
- public class zz
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- string q = @"{{}";
- string[] result = matches(s, p);
- }
-
- public static string hello(string s, string p)
- {
- Match match = Regex.Match(s, p);
- string fullMatch = match.Value;
- }
- }
- '@
-
- function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $r = '(?<a>\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $b + '\s*(\([^)]*\))*\s*\{(?>(?<d>(\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $a + '\s*(\([^)]*\))*\s*\{(?>[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}))|[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22\x27](\r?\n|.)*?[\x22\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
-
- getFuncText -a "Main"
- "--------------------------"
- getFuncText -a "Main" -b "zz"
复制代码
作者: idwma 时间: 2023-5-26 21:48
回复 10# 小白龙 - function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $r = '(?<a>\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $b + '\s*(\([^)]*\))*\s*\{(?>((\r?\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>' + $a + '\s*(\([^)]*\))*\s*\{\s*(?<d>(?>[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!)))\}))|[^{}\/\x22\x27]+|\/\/[^\n]+|/\*(\r?\n|.)*?\*/|[\x22\x27](\r?\n|.)*?[\x22\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
复制代码
作者: 小白龙 时间: 2023-5-26 22:15
本帖最后由 小白龙 于 2023-5-26 22:16 编辑
回复 11# idwma
多谢大佬, 请问, 现在写的正则这么复杂, 能适应 函数体{}花括号内的所有情况吗?
换句话说, 能取到{}内各种情况下的文本了吧
作者: idwma 时间: 2023-5-26 22:16
回复 12# 小白龙
不太清楚碰上了再改
作者: 小白龙 时间: 2023-5-26 22:29
回复 13# idwma
我让GPT优化精简正则, 怎么改都是错的, 正则太长了, 如果有更可靠, 更简洁的方法就好了
作者: idwma 时间: 2023-5-27 09:25
回复 14# 小白龙 - function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $c='private|public|static'
- $d='[^{}\/\x22\x27\r\n]+|\/\/[^\r\n]+|/\*.*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))'
- $r = '(?s)('+$c+'|\s+)*class\s+'+$b+'\s*\{(?>('+$c+'|void|\s+)*'+$a+'\s*(\([^)]*\))*\s*\{\s*(?<d>(?>'+$d+')\}|'+$d+'\}'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
复制代码
作者: idwma 时间: 2023-5-27 15:06
本帖最后由 idwma 于 2023-5-27 15:07 编辑
还可以试试这个- function getFuncText($a, $b)
- {
- if (!$b) { $b = '\S+' }
- $r = '(?s)public\sclass\s'+$b+'\s*\{.+?(private|public|static|void|\s+)*'+$a+'\s*(\([^)]*\))*\s*\{\s*(?<d>(?>[^{}\/\x22\x27\r\n]+|\/\/[^\r\n]+|/\*.*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|\r?\n|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!)))\}'
- [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
- }
复制代码
作者: 小白龙 时间: 2023-5-27 17:58
回复 16# idwma
多谢大佬, 可以正确输出, 和前面那个原理一样吗? 只是精简了一下吗
作者: 小白龙 时间: 2023-5-27 18:02
本帖最后由 小白龙 于 2023-5-27 18:04 编辑
回复 16# idwma
$s = gc -Path "$HOME\Desktop\abc.txt"
用gc获取文件中的字符串, 多行的结果不正确 ,并在一行了, 把字符串写在代码中没事- $s = @'
- using System;
-
- public class xx
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
-
- string p = @"}";
- string p = @"}";
- string s = "xzc abc(s \"(abc)\")); dfg()";
- }
-
- public static string hello(string s, string p)
- {
- string fullMatch = match.Value;
- }
- }
-
- public class zz
- {
- public static void Main()
- {
- string s = "xzc abc(s \"(abc)\")); dfg()";
- string p = @"}";
- }
-
- public static string hello(string s, string p)
- {
- string fullMatch = match.Value;
- }
- }
- '@
复制代码
作者: idwma 时间: 2023-5-27 20:10
回复 17# 小白龙
是什么地方不懂
回复 18# 小白龙
gc得到的是数组,要转成字符
作者: 小白龙 时间: 2023-5-27 20:37
回复 19# idwma
多谢提醒, 加了一个-raw就可以了
作者: 小白龙 时间: 2023-5-27 21:02
回复 19# idwma
大佬, 新的这个正则的执行速度比前面的那个要快多了
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |