找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 37619|回复: 20

[问题求助] PowerShell正则平衡组获取{}内多行文本

[复制链接]
发表于 2023-5-26 17:06:36 | 显示全部楼层 |阅读模式
下面要处理的字符串变量$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)(?!))\})'
  1. $s = @'
  2. using System;

  3. public class xx
  4. {
  5.         public static void Main()
  6.         {
  7.                 string s = "xzc abc(s "(abc)")); dfg()";
  8.                 string p = @"}";
  9.                 string q = @"}{{";
  10.                 string[] result = matches(s, p);
  11.         }
  12.        
  13.         public static string hello(string s, string p)
  14.         {
  15.                 Match match = Regex.Match(s, p);
  16.                 string fullMatch = match.Value;
  17.         }
  18. }

  19. public class zz
  20. {
  21.         public static void Main()
  22.         {
  23.                 string s = "xzc abc(s "(abc)")); dfg()";
  24.                 string p = @"}";
  25.                 string q = @"{{}";
  26.                 string[] result = matches(s, p);
  27.         }
  28.        
  29.         public static string hello(string s, string p)
  30.         {
  31.                 Match match = Regex.Match(s, p);
  32.                 string fullMatch = match.Value;
  33.         }
  34. }
  35. '@

  36. $regex = '(?<=Main\s*\(\)\s*\{)(?<BODY>(?:[^{}]+|(?<OPEN>\{)|(?<-OPEN>\}))*)(?(OPEN)(?!))(?=\})'

  37. if ($s -match $regex)
  38. {
  39.         $match = $Matches['BODY']
  40.         Write-Output $match
  41. }
复制代码
发表于 2023-5-26 18:46:15 | 显示全部楼层
本帖最后由 idwma 于 2023-5-26 18:55 编辑
  1. function getFuncText($a,$b){
  2. if(!$b){$b='\S+'}
  3. $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)(?!))\})'
  4. [regex]::Matches($s, $r).groups|?{$_.name -eq 'd'}|%{$_.captures.value}
  5. }
复制代码
 楼主| 发表于 2023-5-26 18:58:21 | 显示全部楼层
回复 2# idwma


    多谢大佬, 试了一下, 没有输出
  1. $s = @'
  2. using System;

  3. public class xx
  4. {
  5.         public static void Main()
  6.         {
  7.                 string s = "xzc abc(s "(abc)")); dfg()";
  8.                 string p = @"}";
  9.                 string q = @"}{{";
  10.                 string[] result = matches(s, p);
  11.         }
  12.        
  13.         public static string hello(string s, string p)
  14.         {
  15.                 Match match = Regex.Match(s, p);
  16.                 string fullMatch = match.Value;
  17.         }
  18. }

  19. public class zz
  20. {
  21.         public static void Main()
  22.         {
  23.                 string s = "xzc abc(s "(abc)")); dfg()";
  24.                 string p = @"}";
  25.                 string q = @"{{}";
  26.                 string[] result = matches(s, p);
  27.         }
  28.        
  29.         public static string hello(string s, string p)
  30.         {
  31.                 Match match = Regex.Match(s, p);
  32.                 string fullMatch = match.Value;
  33.         }
  34. }
  35. '@

  36. function getFuncText($a, $b)
  37. {
  38.         if (!$b) { $b = '\S+' }
  39.         $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)(?!))\})'
  40.         [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  41. }

  42. getFuncText  -a "Main"
  43. "--------------------------"
  44. getFuncText -a "Main" -b "zz"
复制代码
发表于 2023-5-26 19:04:33 | 显示全部楼层
回复 3# 小白龙


    测过是有的
 楼主| 发表于 2023-5-26 19:09:30 | 显示全部楼层
回复 4# idwma


    我的没有任何输出, window7 x64 powershll 5.1
发表于 2023-5-26 19:34:02 | 显示全部楼层
回复 5# 小白龙


    用win7 5.1测了也是有的
 楼主| 发表于 2023-5-26 20:03:00 | 显示全部楼层
回复 6# idwma

这是我测试的文件
    https://t.wss.ink/f/bax41qzzn9f 复制链接到浏览器打开
 楼主| 发表于 2023-5-26 20:50:17 | 显示全部楼层
回复 6# idwma

奇怪, 在另一台电脑上也不行,
发表于 2023-5-26 21:06:03 | 显示全部楼层
  1. function getFuncText($a, $b)
  2. {
  3.         if (!$b) { $b = '\S+' }
  4.         $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)(?!))\})'
  5.         [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  6. }
复制代码
 楼主| 发表于 2023-5-26 21:15:41 | 显示全部楼层
回复 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);

        }
  1. $s = @'
  2. using System;

  3. public class xx
  4. {
  5.         public static void Main()
  6.         {
  7.                 string s = "xzc abc(s "(abc)")); dfg()";
  8.                 string p = @"}";
  9.                 string q = @"}{{";
  10.                 string[] result = matches(s, p);
  11.         }
  12.        
  13.         public static string hello(string s, string p)
  14.         {
  15.                 Match match = Regex.Match(s, p);
  16.                 string fullMatch = match.Value;
  17.         }
  18. }

  19. public class zz
  20. {
  21.         public static void Main()
  22.         {
  23.                 string s = "xzc abc(s "(abc)")); dfg()";
  24.                 string p = @"}";
  25.                 string q = @"{{}";
  26.                 string[] result = matches(s, p);
  27.         }
  28.        
  29.         public static string hello(string s, string p)
  30.         {
  31.                 Match match = Regex.Match(s, p);
  32.                 string fullMatch = match.Value;
  33.         }
  34. }
  35. '@

  36. function getFuncText($a, $b)
  37. {
  38.         if (!$b) { $b = '\S+' }
  39.         $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)(?!))\})'
  40.         [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  41. }

  42. getFuncText  -a "Main"
  43. "--------------------------"
  44. getFuncText -a "Main" -b "zz"
复制代码
发表于 2023-5-26 21:48:52 | 显示全部楼层
回复 10# 小白龙
  1. function getFuncText($a, $b)
  2. {
  3.         if (!$b) { $b = '\S+' }
  4.         $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)(?!))\})'
  5.         [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  6. }
复制代码

评分

参与人数 1技术 +1 收起 理由
小白龙 + 1 乐于助人

查看全部评分

 楼主| 发表于 2023-5-26 22:15:04 | 显示全部楼层
本帖最后由 小白龙 于 2023-5-26 22:16 编辑

回复 11# idwma

多谢大佬, 请问, 现在写的正则这么复杂, 能适应 函数体{}花括号内的所有情况吗?
换句话说, 能取到{}内各种情况下的文本了吧
发表于 2023-5-26 22:16:56 | 显示全部楼层
回复 12# 小白龙


    不太清楚碰上了再改
 楼主| 发表于 2023-5-26 22:29:17 | 显示全部楼层
回复 13# idwma

我让GPT优化精简正则, 怎么改都是错的, 正则太长了, 如果有更可靠, 更简洁的方法就好了
发表于 2023-5-27 09:25:20 | 显示全部楼层
回复 14# 小白龙
  1. function getFuncText($a, $b)
  2. {
  3.         if (!$b) { $b = '\S+' }
  4.         $c='private|public|static'
  5.         $d='[^{}\/\x22\x27\r\n]+|\/\/[^\r\n]+|/\*.*?\*/|[\x22][^\x22]*[\x22]|[\x27][^\x27]*[\x27]|[^{}]|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))'
  6.         $r = '(?s)('+$c+'|\s+)*class\s+'+$b+'\s*\{(?>('+$c+'|void|\s+)*'+$a+'\s*(\([^)]*\))*\s*\{\s*(?<d>(?>'+$d+')\}|'+$d+'\}'
  7.         [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  8. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 00:42 , Processed in 0.023772 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表