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

[问题求助] powershell按先后顺序成对匹配花括号

[复制链接]
发表于 2024-1-22 17:37:46 | 显示全部楼层 |阅读模式
本帖最后由 小白龙 于 2024-1-22 17:40 编辑

又一个平衡组难题, gpt也没搞定, 是我描述的不够清楚吗? 求路过大佬支招
下面注释中有详细描述
  1. cls
  2. <#
  3. 用powershell代码加1条正则来判断某多行文本末尾的3个关花括号 } 是否分别,成对地匹配前面的 namespace xxx, public class xxx,  public xxx 后的开括号 {
  4. 1.如果有三个匹配, 就输出: 三个匹配
  5. 2.如果有两个匹配, 就输出: 两个匹配
  6. 3.如果有一个匹配, 就输出: 一个匹配
  7. 4.如果无一个匹配, 就输出: 无匹配
  8. 注意:
  9. 1.末尾有几个括号就匹配对应的几层, 层要按上面的先后顺序
  10. 2.开花括号 { 有时没有占独一行,而是在其上一行的末尾, 例如: $s2 和 $s3
  11. 3.开花括号 { 前的xxx 表示不确定的文本, xxx前面的文本则是严格匹配的文本
  12. #>

  13. $s1 = @'
  14. using System;

  15. namespace _1
  16. {
  17.         public class _2
  18.         {
  19.                 public static void Main()
  20.                 {
  21.                         string s1 = "中";
  22.                         string s2 = "国";
  23.                 }
  24.         }
  25. }
  26. '@
  27. #输出 => 三个匹配

  28. $s2 = @'
  29. using System;

  30. public class _2 {
  31.         public static void Main() {
  32.                 string s1 = "中";
  33.                 string s2 = "国";
  34. }
  35. }
  36. '@
  37. #输出 => 两个匹配

  38. $s3 = @'
  39. using System;

  40. public static void Main(){
  41.         string s1 = "中";
  42.         string s2 = "国";
  43. }
  44. '@
  45. #输出 => 一个匹配

  46. $s4 = @'
  47. using System;

  48. string s1 = "中";
  49. string s2 = "国";
  50. '@
  51. #输出 => 无匹配
复制代码
发表于 2024-1-22 18:17:46 | 显示全部楼层
如果是下面那样的话输出结果是啥???

  1. $ss = @'
  2. using System;
  3. public static void Main(){
  4. //}}}}}}}{{{{{{{{
  5.         string s1 = "中{{{{{{{{{{{";
  6.         string s2 = "国}}}}}}}";
  7. }
  8. //}}}}}}}
  9. '@
复制代码
 楼主| 发表于 2024-1-22 18:34:34 | 显示全部楼层
回复 2# Five66


       这情况应该极少遇到
 楼主| 发表于 2024-1-22 18:40:01 | 显示全部楼层
下面是gpt的回答, 没匹配出三个, 另外也太复杂了, 有没有可能一行正则就搞定了?
  1. function CountBraces
  2. {
  3.         param (
  4.                 [string]$inputText
  5.         )
  6.        
  7.         # 匹配 namespace xxx, public class xxx, public xxx 后的开括号 {
  8.         $regex = '(?<=namespace|public\sclass|public)(?:.*{)'
  9.        
  10.         # 提取匹配的部分
  11.         $matches = [regex]::Matches($inputText, $regex)
  12.        
  13.         # 计算匹配的层级数
  14.         $braceCounts = $matches | ForEach-Object {
  15.                 $braceCount = 0
  16.                 $charArray = $_.Value.ToCharArray()
  17.                
  18.                 # 逐字符检查层级
  19.                 foreach ($char in $charArray)
  20.                 {
  21.                         if ($char -eq '{')
  22.                         {
  23.                                 $braceCount++
  24.                         }
  25.                         elseif ($char -eq '}')
  26.                         {
  27.                                 $braceCount--
  28.                         }
  29.                 }
  30.                
  31.                 $braceCount
  32.         }
  33.        
  34.         # 统计不同层级的次数
  35.         $result = $braceCounts | Group-Object | ForEach-Object {
  36.                 "$($_.Count)个匹配"
  37.         }
  38.        
  39.         # 输出结果
  40.         $result -join ", "
  41. }

  42. # 测试样例
  43. $testCases = @(
  44.         $s1,
  45.         $s2,
  46.         $s3,
  47.         $s4
  48. )

  49. $testCases | ForEach-Object {
  50.         CountBraces $_
  51.         Write-Host '---'
  52. }
复制代码
发表于 2024-1-22 19:09:58 | 显示全部楼层
把之前的改改
  1. $p = "(?=((?:namespace|public)[^{]+\{(?:[^{}]+|(?<Open>)\{|(?<-Open>)\})*(?(Open)(?!))\}))"
  2. [Regex]::Matches($s, $p).count + '个'
复制代码
 楼主| 发表于 2024-1-22 20:03:44 | 显示全部楼层
回复 5# idwma

多谢大佬, 提示类型错误, 改为下面就可以了
[Regex]::Matches($s1, $p).count.ToString() + '个'


有两个问题, 我看正则中有(?:namespace|public) 这里只有第一层和第三层的, 第二层的public class没有, 如果实际例子中变成了public kkkkk也会被匹配上了, 如果加上去, 这些会按层次先后去匹配吗?

还有难题, 就缺哪层时就补哪层怎么解决呢?
例如, 有两层, 缺第一层, 就在两层外补上namespace A {  ........  }
例如, 有一层, 缺前两层, 就在该层外补上namespace A {   public class B {  ........  }   }
例如, 三层全缺, 就在外补上namespace A{   public class B { public static void Main() {  ........  }  }   }
 楼主| 发表于 2024-1-22 20:07:30 | 显示全部楼层
回复 5# idwma


    我看到过哪个正则的文章中有写到, 能把匹配的值填充到 <变量名> 中, 之后就可以使用这个变量, 用这个方法感觉解决我楼上的补层的问题很不错, 但是不懂怎么操作
发表于 2024-1-22 20:13:49 | 显示全部楼层
回复 6# 小白龙


    看不懂,不会了
状态就像先这样,再这样,然后这样。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-17 02:29 , Processed in 0.010318 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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