标题: [问题求助] [已解决]用正则表达式中的平衡组删除或修改特定字段 [打印本页]
作者: 小白龙 时间: 2023-5-9 14:20 标题: [已解决]用正则表达式中的平衡组删除或修改特定字段
本帖最后由 小白龙 于 2023-5-10 18:19 编辑
我要修改的多行字符串是一段C#代码, 里面{}环环相套! 可能必须要用平衡组了!
要点1: 类名和函数名后面的 { 的位置有如下两种情况
情况一 { 在新的行中
string FUN1()
{
}
情况二 { 在同一行的末尾
string FUN1() {
}
要点2: 函数的参数里可能有()嵌套()的情况
函数体里可能有{}嵌套{}的情况
要点3: 既要界定返回值类型的文本, 又要判断修饰词是否存在
感觉那三个需求, 用2个正则平衡式应该可以实现
下面代码的注释中有详细的描述, 请求路过大佬帮忙
情况1中的代码可以删除FUN1了, 但是因为没有使用平衡组, 如果{}互相嵌套就不灵了- #--------------------------------------------------------------------情况1: 函数FUN1返回值类型void
-
- $s1 = @'
- using System;
-
- public class CLA
- {
- void FUN1()
- {
- Console.WriteLine("FUN1");
- }
- }
- '@
- $s1 -replace '(?s)void FUN1\(\).*?\}', ''
-
-
- #--------------------------------------------------------------------情况2: 返回值类型改为了 string
-
- $s2 = @'
- using System;
-
- public class CLA
- {
- string FUN1()
- {
- return "FUN1";
- }
- }
- '@
-
- #--------------------------------------------------------------------情况3: 加了修饰词 public
-
- $s3 = @'
- using System;
-
- public class CLA
- {
- public void FUN1()
- {
- Console.WriteLine("FUN1");
- }
- }
- '@
-
- #--------------------------------------------------------------------情况4: 加了修饰词 public static
-
- $s4 = @'
- using System;
-
- public class CLA
- {
- public static string FUN1()
- {
- return "FUN1";
- }
- }
- '@
-
- # 需求1 用1个正则表达式能删除指定函数名的函数, 要考虑函数名前的多种修饰词的情况
- #例如: 把上面四种情况中的 FUN1 函数删除掉
-
- # 需求2 用正则表达式: 修改指定函数名前的修饰词(不要修改返回值类型)
- #例如: 把 FUN1 函数的修饰词改为 public static (如果没有修饰词就加上,如果有就修改)
-
- # 需求3 用正则表达式: 修改指定类名前的修饰词
- #例如: 把 CLA 类的修饰词改为 private (如果没有修饰词就加上,如果有就修改)
复制代码
作者: 小白龙 时间: 2023-5-9 14:52
本帖最后由 小白龙 于 2023-5-9 15:08 编辑
chatgpt的正则都太局限了也没用平衡组, 求路过大老出招, 优化改进一下!
-replace '(?s)(void|string)\s+FUN1\(\).*?\}', ''
-replace '(?<=\bstring)\s+(?=FUN1\(\))', 'public static'
-replace '(?<=class\s+)\w+', 'private'
作者: idwma 时间: 2023-5-9 17:19
多问几次试试
作者: 小白龙 时间: 2023-5-9 17:46
回复 3# idwma
多谢大佬, 这个正则只适用, void 前置关键字的情况, 还有其它几种
@"void\s+FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}"
作者: 小白龙 时间: 2023-5-9 17:56
回复 3# idwma
替换成前置都能替换成功, 但是前置的关键词情况太多了, 怎样通用呢- #--------------------------------------------------------------------情况1: 函数FUN1返回值类型void
-
- $s1 = @'
- using System;
-
- public class CLA
- {
- void FUN1()
- {
- Console.WriteLine("FUN1");
- }
- }
- '@
-
- #--------------------------------------------------------------------情况2: 返回值类型改为了 string
-
- $s2 = @'
- using System;
-
- public class CLA
- {
- string FUN1()
- {
- return "FUN1";
- }
- }
- '@
-
- #--------------------------------------------------------------------情况3: 加了修饰词 public
-
- $s3 = @'
- using System;
-
- public class CLA
- {
- public void FUN1()
- {
- Console.WriteLine("FUN1");
- }
- }
- '@
-
- #--------------------------------------------------------------------情况4: 加了修饰词 public static
-
- $s4 = @'
- using System;
-
- public class CLA
- {
- public static string FUN1()
- {
- return "FUN1";
- }
- }
- '@
-
- # 使用正则表达式删除指定函数
- $s1 -replace '(?s)void\s+FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}'
- $s2 -replace '(?s)string\s+FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}'
- $s3 -replace '(?s)public void\s+FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}'
- $s4 -replace '(?s)public static string\s+FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}'
复制代码
作者: idwma 时间: 2023-5-9 17:57
回复 4# 小白龙 - .*FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}
复制代码
作者: 小白龙 时间: 2023-5-9 18:46
回复 6# idwma
多谢大佬, 这个正则可以适应各种情况, 但是必须关闭单行模式才有效, 前面的正则式必须开单行, 为什么这么大差别呢?
作者: 小白龙 时间: 2023-5-9 18:48
回复 6# idwma
下面两个需求, 怎样在上面正则的基础上修改? 搞不太懂, 问了几次chatgpt, 答非所问
# 需求2 用正则表达式: 修改指定函数名前的修饰词(不要修改返回值类型)
#例如: 把 FUN1 函数的修饰词改为 public static (如果没有修饰词就加上,如果有就修改)
# 需求3 用正则表达式: 修改指定类名前的修饰词
#例如: 把 CLA 类的修饰词改为 private (如果没有修饰词就加上,如果有就修改)
作者: idwma 时间: 2023-5-9 20:19
- $s1 -replace '.*(FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','public static $1'
- $s1 -replace '.*(CLA\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','private $1'
复制代码
作者: idwma 时间: 2023-5-9 20:26
回复 7# 小白龙
不知道
作者: 小白龙 时间: 2023-5-10 07:31
本帖最后由 小白龙 于 2023-5-10 07:33 编辑
回复 9# idwma - $s1 -replace '.*(FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','public static $1'
复制代码
用上面的正则会删除函数的返回值类型, 返回值类型也有很多种, 不固定, 下面示例中红色字是添加的修饰词, 其后蓝色字是返回值类型,不应修改
修改前
public class CLA
{
void FUN1()
{
Console.WriteLine("FUN1");
}
}
修改后
public class CLA
{
public static void FUN1()
{
Console.WriteLine("FUN1");
}
}
作者: 小白龙 时间: 2023-5-10 07:40
本帖最后由 小白龙 于 2023-5-10 07:53 编辑
回复 9# idwma
返回值类型有下面几种, 都在函数名前, 除了第2个在括号中有空格之外, 其它的情况都是个整体, 内部没有空格, 这个好像有点难度了, 问gpt 完全不知道在说什么
int? GetNullableInt()
(string, int) GetPersonInfo()
IEnumerable<int> GetNumbers()
async Task<string> DownloadFileAsync(string url)- // 返回Nullable类型
- int? GetNullableInt()
- {
- int? result = null;
- return result;
- }
-
- // 返回Tuple类型
- (string, int) GetPersonInfo()
- {
- string name = "张三";
- int age = 20;
- return (name, age);
- }
-
- // 返回IEnumerable类型
- IEnumerable<int> GetNumbers()
- {
- yield return 1;
- yield return 2;
- yield return 3;
- }
-
- // 返回Task类型
- async Task<string> DownloadFileAsync(string url)
- {
- HttpClient client = new HttpClient();
- HttpResponseMessage response = await client.GetAsync(url);
- string content = await response.Content.ReadAsStringAsync();
- return content;
- }
复制代码
作者: idwma 时间: 2023-5-10 10:40
本帖最后由 idwma 于 2023-5-10 11:33 编辑
回复 12# 小白龙
是这样吗- $s1 -replace '(?<a>\s*)(private|public|static|async|(?<b>(string|void|int\?|\(string, int\)|IEnumerable<int>|Task<string>)\s*)|\s*)*(?<c>FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','${a}public static ${b}${c}'
复制代码
再试试这样- $s1 -replace '(?<a>\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*)|\s*)*(?<c>FUN1\s*\(\s*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','${a}public static ${b}${c}'
复制代码
作者: 小白龙 时间: 2023-5-10 13:07
回复 13# idwma
多谢大佬, 这种具体限定几个关键字有个问题, 就是返回值类型还有很多, 例如 string[]
但是有个总规律:
函数名前都有一个空格
情况1. 空格前如果是个关括号 ) 则匹配的开括号( 这中间允许有空格, 像下面这样
(string, int) GetPersonInfo()
情况2.空格前都是连续的, 没有空格, 像#12楼的例子
就这两种情况
作者: idwma 时间: 2023-5-10 13:29
回复 14# 小白龙
试试13楼的第二个,只用指定修饰符应该没多少个缺的自己加上去
作者: 小白龙 时间: 2023-5-10 16:20
回复 15# idwma
我测试的这个函数,
DownloadFileAsync
, 一直运行, 停不下来了, 我就改了下面两个红色字的地方
(?<a>\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*)|\s*)*(?<c>DownloadFileAsync\s*\(.*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})', '${a}public static ${b}${c}- $s = @'
- // 返回Nullable类型
- int? GetNullableInt()
- {
- int? result = null;
- return result;
- }
-
- // 返回Tuple类型
- (string, int) GetPersonInfo()
- {
- string name = "张三";
- int age = 20;
- return (name, age);
- }
-
- // 返回IEnumerable类型
- IEnumerable<int> GetNumbers()
- {
- yield return 1;
- yield return 2;
- yield return 3;
- }
-
- // 返回Task类型
- async Task<string> DownloadFileAsync(string url)
- {
- HttpClient client = new HttpClient();
- HttpResponseMessage response = await client.GetAsync(url);
- string content = await response.Content.ReadAsStringAsync();
- return content;
- }
- '@
-
- $s -replace '(?<a>\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*)|\s*)*(?<c>DownloadFileAsync\s*\(.*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})', '${a}public static ${b}${c}'
复制代码
作者: idwma 时间: 2023-5-10 16:58
回复 16# 小白龙 - $s -replace '(?<a>\n\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*(?<c>DownloadFileAsync\s*\([^)]*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})','${a}public static ${b}${c}'
复制代码
作者: 小白龙 时间: 2023-5-10 17:12
回复 17# idwma
那个函数修改可以了, 我把正则中的函数名改为另一个 IEnumerable<int> 测试没有效果
作者: idwma 时间: 2023-5-10 17:16
回复 18# 小白龙
把你改的发出来看看
作者: 小白龙 时间: 2023-5-10 17:34
回复 19# idwma - $s = @'
- // 返回Nullable类型
-
- // 返回IEnumerable类型
- IEnumerable<int> GetNumbers()
- {
- yield return 1;
- yield return 2;
- yield return 3;
- }
- '@
-
- $s -replace '(?<a>\s*)(private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*)|\s*)*(?<c>GetNumbers\s*\(.*\)\s*\{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\})', '${a}public static ${b}${c}'
复制代码
作者: 小白龙 时间: 2023-5-10 17:38
回复 19# idwma
我让gpt写了一下注释- $s -replace '(?x) # 开启忽略空格和注释选项
- (?<a>\n\s*) # 匹配换行符和空格并捕获到名为"a"的组中
- (private|public|static|async|(?<b>(\b\S+|\([^()]+\))\s*))*
- # 匹配访问修饰符和方法类型,并将它们捕获到名为"b"的组中
- (?<c> # 匹配方法名和参数列表,并将其捕获到名为"c"的组中
- DownloadFileAsync\s* # 匹配方法名
- \([^)]*\)\s* # 匹配参数列表
- \{(?:[^{}]+|\{(?<DEPTH>)|\}(?<-DEPTH>))*?(?(DEPTH)(?!))\}
- # 匹配方法体
- )',
- '${a}public static ${b}${c}' # 将匹配到的代码块替换为公共静态方法,并确保代码可执行
复制代码
作者: idwma 时间: 2023-5-10 17:43
回复 20# 小白龙
再看看17楼
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |