标题: [问题求助] powershell按先后顺序成对匹配花括号 [打印本页]
作者: 小白龙 时间: 2024-1-22 17:37 标题: powershell按先后顺序成对匹配花括号
本帖最后由 小白龙 于 2024-1-22 17:40 编辑
又一个平衡组难题, gpt也没搞定, 是我描述的不够清楚吗? 求路过大佬支招
下面注释中有详细描述- cls
- <#
- 用powershell代码加1条正则来判断某多行文本末尾的3个关花括号 } 是否分别,成对地匹配前面的 namespace xxx, public class xxx, public xxx 后的开括号 {
- 1.如果有三个匹配, 就输出: 三个匹配
- 2.如果有两个匹配, 就输出: 两个匹配
- 3.如果有一个匹配, 就输出: 一个匹配
- 4.如果无一个匹配, 就输出: 无匹配
- 注意:
- 1.末尾有几个括号就匹配对应的几层, 层要按上面的先后顺序
- 2.开花括号 { 有时没有占独一行,而是在其上一行的末尾, 例如: $s2 和 $s3
- 3.开花括号 { 前的xxx 表示不确定的文本, xxx前面的文本则是严格匹配的文本
- #>
-
- $s1 = @'
- using System;
-
- namespace _1
- {
- public class _2
- {
- public static void Main()
- {
- string s1 = "中";
- string s2 = "国";
- }
- }
- }
- '@
- #输出 => 三个匹配
-
- $s2 = @'
- using System;
-
- public class _2 {
- public static void Main() {
- string s1 = "中";
- string s2 = "国";
- }
- }
- '@
- #输出 => 两个匹配
-
- $s3 = @'
- using System;
-
- public static void Main(){
- string s1 = "中";
- string s2 = "国";
- }
- '@
- #输出 => 一个匹配
-
- $s4 = @'
- using System;
-
- string s1 = "中";
- string s2 = "国";
- '@
- #输出 => 无匹配
复制代码
作者: Five66 时间: 2024-1-22 18:17
如果是下面那样的话输出结果是啥???- $ss = @'
- using System;
- public static void Main(){
- //}}}}}}}{{{{{{{{
- string s1 = "中{{{{{{{{{{{";
- string s2 = "国}}}}}}}";
- }
- //}}}}}}}
- '@
复制代码
作者: 小白龙 时间: 2024-1-22 18:34
回复 2# Five66
这情况应该极少遇到
作者: 小白龙 时间: 2024-1-22 18:40
下面是gpt的回答, 没匹配出三个, 另外也太复杂了, 有没有可能一行正则就搞定了?- function CountBraces
- {
- param (
- [string]$inputText
- )
-
- # 匹配 namespace xxx, public class xxx, public xxx 后的开括号 {
- $regex = '(?<=namespace|public\sclass|public)(?:.*{)'
-
- # 提取匹配的部分
- $matches = [regex]::Matches($inputText, $regex)
-
- # 计算匹配的层级数
- $braceCounts = $matches | ForEach-Object {
- $braceCount = 0
- $charArray = $_.Value.ToCharArray()
-
- # 逐字符检查层级
- foreach ($char in $charArray)
- {
- if ($char -eq '{')
- {
- $braceCount++
- }
- elseif ($char -eq '}')
- {
- $braceCount--
- }
- }
-
- $braceCount
- }
-
- # 统计不同层级的次数
- $result = $braceCounts | Group-Object | ForEach-Object {
- "$($_.Count)个匹配"
- }
-
- # 输出结果
- $result -join ", "
- }
-
- # 测试样例
- $testCases = @(
- $s1,
- $s2,
- $s3,
- $s4
- )
-
- $testCases | ForEach-Object {
- CountBraces $_
- Write-Host '---'
- }
复制代码
作者: idwma 时间: 2024-1-22 19:09
把之前的改改- $p = "(?=((?:namespace|public)[^{]+\{(?:[^{}]+|(?<Open>)\{|(?<-Open>)\})*(?(Open)(?!))\}))"
- [Regex]::Matches($s, $p).count + '个'
复制代码
作者: 小白龙 时间: 2024-1-22 20:03
回复 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
回复 5# idwma
我看到过哪个正则的文章中有写到, 能把匹配的值填充到 <变量名> 中, 之后就可以使用这个变量, 用这个方法感觉解决我楼上的补层的问题很不错, 但是不懂怎么操作
作者: idwma 时间: 2024-1-22 20:13
回复 6# 小白龙
看不懂,不会了
状态就像先这样,再这样,然后这样。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |