[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] 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)(?!))\})'
  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. public static string hello(string s, string p)
  13. {
  14. Match match = Regex.Match(s, p);
  15. string fullMatch = match.Value;
  16. }
  17. }
  18. public class zz
  19. {
  20. public static void Main()
  21. {
  22. string s = "xzc abc(s \"(abc)\")); dfg()";
  23. string p = @"}";
  24. string q = @"{{}";
  25. string[] result = matches(s, p);
  26. }
  27. public static string hello(string s, string p)
  28. {
  29. Match match = Regex.Match(s, p);
  30. string fullMatch = match.Value;
  31. }
  32. }
  33. '@
  34. $regex = '(?<=Main\s*\(\)\s*\{)(?<BODY>(?:[^{}]+|(?<OPEN>\{)|(?<-OPEN>\}))*)(?(OPEN)(?!))(?=\})'
  35. if ($s -match $regex)
  36. {
  37. $match = $Matches['BODY']
  38. Write-Output $match
  39. }
复制代码

本帖最后由 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. }
复制代码

TOP

回复 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. public static string hello(string s, string p)
  13. {
  14. Match match = Regex.Match(s, p);
  15. string fullMatch = match.Value;
  16. }
  17. }
  18. public class zz
  19. {
  20. public static void Main()
  21. {
  22. string s = "xzc abc(s \"(abc)\")); dfg()";
  23. string p = @"}";
  24. string q = @"{{}";
  25. string[] result = matches(s, p);
  26. }
  27. public static string hello(string s, string p)
  28. {
  29. Match match = Regex.Match(s, p);
  30. string fullMatch = match.Value;
  31. }
  32. }
  33. '@
  34. function getFuncText($a, $b)
  35. {
  36. if (!$b) { $b = '\S+' }
  37. $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)(?!))\})'
  38. [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  39. }
  40. getFuncText  -a "Main"
  41. "--------------------------"
  42. getFuncText -a "Main" -b "zz"
复制代码

TOP

回复 3# 小白龙


    测过是有的

TOP

回复 4# idwma


    我的没有任何输出, window7 x64 powershll 5.1

TOP

回复 5# 小白龙


    用win7 5.1测了也是有的

TOP

回复 6# idwma

这是我测试的文件
    https://t.wss.ink/f/bax41qzzn9f 复制链接到浏览器打开

TOP

回复 6# idwma

奇怪, 在另一台电脑上也不行,

TOP

  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. }
复制代码

TOP

回复 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. public static string hello(string s, string p)
  13. {
  14. Match match = Regex.Match(s, p);
  15. string fullMatch = match.Value;
  16. }
  17. }
  18. public class zz
  19. {
  20. public static void Main()
  21. {
  22. string s = "xzc abc(s \"(abc)\")); dfg()";
  23. string p = @"}";
  24. string q = @"{{}";
  25. string[] result = matches(s, p);
  26. }
  27. public static string hello(string s, string p)
  28. {
  29. Match match = Regex.Match(s, p);
  30. string fullMatch = match.Value;
  31. }
  32. }
  33. '@
  34. function getFuncText($a, $b)
  35. {
  36. if (!$b) { $b = '\S+' }
  37. $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)(?!))\})'
  38. [regex]::Matches($s, $r).groups | ?{ $_.name -eq 'd' } | %{ $_.captures.value }
  39. }
  40. getFuncText  -a "Main"
  41. "--------------------------"
  42. getFuncText -a "Main" -b "zz"
复制代码

TOP

回复 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

评分人数

TOP

本帖最后由 小白龙 于 2023-5-26 22:16 编辑

回复 11# idwma

多谢大佬, 请问, 现在写的正则这么复杂, 能适应 函数体{}花括号内的所有情况吗?
换句话说, 能取到{}内各种情况下的文本了吧

TOP

回复 12# 小白龙


    不太清楚碰上了再改

TOP

回复 13# idwma

我让GPT优化精简正则, 怎么改都是错的, 正则太长了, 如果有更可靠, 更简洁的方法就好了

TOP

回复 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. }
复制代码

TOP

返回列表