标题: [问题求助] PowerShell怎样用正则在第1个{后面加1行文本? [打印本页]
作者: meixi 时间: 2023-4-9 18:36 标题: PowerShell怎样用正则在第1个{后面加1行文本?
大家好, 我想使用正则在第1个{后面加一行文本[123], 【注意 123 是随机3位数字 即:下面$num的值】, 但是这行文本左边的空白字符, 要与其下的行前的空白字符完全相同,
另外, 处理前要先检查一下, { 下有没有 [123] 的行, 有的话, 就不要重复加了, 没有时才加!
下面代码有两个例子, 请路过高手支招, 提前感谢!- $num = "[$(Get-Random -ma 999 -mi 100)]"
- $num
-
- #################################################################
-
- $s = @'
- zzz
- xxx
-
- abc bbb
- {
- ccc
- {
- ddd
- }
- }
- '@
- <# 正则处理后的结果:
- zzz
- xxx
-
- abc bbb
- {
- [123]
- ccc
- {
- ddd
- }
- }
- #>
-
- #################################################################
-
-
- $s2 = @'
- zzz
- xxx
-
- abc kkk{
- ooo
- {
- ddd
- }
- }
- '@
-
- <# 正则处理后的结果:
- zzz
- xxx
-
- abc kkk{
- [888]
- ooo
- {
- ddd
- }
- }
- #>
复制代码
作者: meixi 时间: 2023-4-9 21:00
下面正则还不完美
$s -replace '(?<=\{)\s*', " $num"
作者: WHY 时间: 2023-4-9 22:45
本帖最后由 WHY 于 2023-4-10 00:01 编辑
- $s = @'
- zzz
- xxx
-
- abc bbb
- {
- [123]
- ccc
- {
- ddd
- }
- }
- '@
-
- #$num = '[' + (Get-Random -ma 999 -mi 100) + ']';
- $num = '[123]';
- $s -replace ('^(?>[^{]*){(\r?\n[ \t]+)(?!\' + $num + ')'), ('$&' + $num + '$1');
-
- pause
复制代码
作者: meixi 时间: 2023-4-9 23:16
回复 3# WHY
多谢大佬帮忙!
下面这个要求能在上面正则中一并做判断吗?
处理前要先检查一下, { 下有没有 [123] 的行, 有的话, 就不要重复加了, 没有时才加!
作者: meixi 时间: 2023-4-9 23:25
本帖最后由 meixi 于 2023-4-9 23:28 编辑
回复 3# WHY
大佬, 正则中的下面两点看不懂, 能解释一下吗? 好像在有的软件中不通用
')' 和 '$&'
作者: WHY 时间: 2023-4-10 00:02
回复 4# meixi
已改
作者: Five66 时间: 2023-4-10 07:00
我脑子不够使,只会分成多条代码来
作者: meixi 时间: 2023-4-10 07:22
回复 3# WHY
W大, 我的软件不支持 正则中的 $& 写法, 但支持如下的写法,
$` $' $0 $1 $2 ${n}
作者: meixi 时间: 2023-4-10 07:23
回复 7# Five66
大佬, 能帮写个通用一些的正则吗? W大的正则, 我的软件不支持
作者: meixi 时间: 2023-4-10 07:25
本帖最后由 meixi 于 2023-4-10 07:27 编辑
回复 3# WHY
我用chatgpt解析了一下正则: 红色字部分不理解, 是解释错了吗?
问:
解释下面的正则式
$s -replace '^(?>[^{]*){(\r?\n[ \t]+)(?!\[123])', '$&[123]$1';
答:
这个正则表达式可以分成三部分:
^(?>[^{]*){ 匹配以 { 开头的行,并排除其中的尖括号 >。
(\r?\n[ \t]+) 匹配一个换行符后跟至少一个空格或制表符的字符序列,并将其捕获。
(?!\[123]) 使用负向零宽断言,判断匹配结果后面的字符串中是否不存在 [123]。
整个正则表达式的作用是匹配以 { 开头的行,但排除某些特定的行,只在需要的行前添加标记 [123]。
这个正则表达式在代码中的作用是如果某一行以 { 开头,但不是一些特定的行(即这些行中不存在 [123] 标记),就在这行前面添加 [123]。可以配合字符串替换函数使用,实现字符串的标记和修改。
作者: WHY 时间: 2023-4-10 08:56
回复 10# meixi
ChatGPT瞎说,我来解释一下吧
$s -replace '^(?>[^{]*){(\r?\n[ \t]+)(?!\[123])', '$&[123]$1';
(?>[^{]*) 是固化分组(原子组),作用是禁止回溯,当匹配不成功时可以提高效率。有些流派支持,有些不支持。
'^(?>[^{]*) #开头不是{字符,这样的字符重复0次或多次。
{ #接着是{字符
(\r?\n[ \t]+) #接着是一个回车换行,多个空格或Tab字符,把这些字符存放到子匹配Groups[1]中(即$1中)
(?!\[123]) #后面不是[123],这个是零宽断言。
'
每种流派的正则并不完全相同,不可能做到通用。试试
$s -replace '^[^{]*{(\r?\n[ \t]+)(?!\[123])', '$0[123]$1';
作者: meixi 时间: 2023-4-10 09:26
回复 11# WHY
感谢大佬解释,
我的软件执行后, 会添加一行, 行里只有一个 { 左面的空间也是对的, 把 { 换成 [123]就对了
作者: meixi 时间: 2023-4-10 09:35
本帖最后由 meixi 于 2023-4-10 09:37 编辑
(?>[^{]*)
?后面有个>是什么意思呢, 我的软件只支持下面的,
(?<=)
(?<!)
(?=)
(?!)
___________________________________________________________2
(?!\[123])
上面的!后有\应该是转义吧, 为什么后面那个]不用转义?
作者: WHY 时间: 2023-4-10 10:14
回复 13# meixi
1.我已经告诉你了,固化分组
http://www.bathome.net/post.php? ... p;extra=&page=1
2.我已经给了你一个不用固化分组的、看起来"通用"的脚本,何不试试呢
3.我感觉你使用的"程序"与PowerShell不搭边,为啥一定要在PowerShell里写正则呢
4.(?!\[123]) 左括号已经转义,孤零零的右括号不会引起歧义,无需转义。
作者: meixi 时间: 2023-4-10 10:25
回复 14# WHY
2.我已经给了你一个不用固化分组的、看起来"通用"的脚本,何不试试呢
我已经试了, 上面就是执行后的结果
作者: meixi 时间: 2023-4-10 10:27
回复 14# WHY 复制代码
下面那个链接打不开, 一点就打开编辑器了
作者: meixi 时间: 2023-4-10 10:32
回复 14# WHY
3.我感觉你使用的"程序"与PowerShell不搭边,为啥一定要在PowerShell里写正则呢
软件是个英文版的定时任务软件,
它支持powershell, 也支持自己内部的正则, 但是powershell代码执行时反应太慢
作者: WHY 时间: 2023-4-10 11:05
回复 16# meixi
网上随便找篇文章,就知道什么是"固化分组"
https://blog.csdn.net/liaowenxiong/article/details/118459839
作者: meixi 时间: 2023-4-10 14:49
本帖最后由 meixi 于 2023-4-10 14:51 编辑
回复 11# WHY
W大, 我把下面正则进行各种修改, 我那软件都稳稳输出只有 { 的一行, 真是怪了, 还有别的方法吗? $0 在那软件是正则的所有匹配 $` 是前面的 $' 是后面的
$s -replace '^[^{]*{(\r?\n[ \t]+)(?!\[123])', '$0[123]$1';
作者: WHY 时间: 2023-4-10 18:27
回复 19# meixi
别的方法就是:
1.扔掉你那个辣鸡软件,用PowerShell就行;
2.不要用正则,用 For 循环 + If 判断
作者: WHY 时间: 2023-4-10 18:29
- $s = @'
- zzz
- xxx
-
- abc bbb
- {
- [123]
- {
- ddd
- }
- }
- '@
-
- #$num = '[' + (Get-Random -ma 999 -mi 100) + ']';
- $num = '[123]';
- $arr = $s -split "`r`n";
- $s1 = '';
-
- for ($i=0; $i -lt $arr.Count; $i++){
- If ($s1.IndexOf( '{') -ge 0){ #上一行含"{"字符
- If ($arr[$i].IndexOf($num) -lt 0){ #当前行不含[123]
- $x = $arr[$i].TrimStart(); #删掉开头的空格或跳格
- $y = $arr[$i].Replace($x, '') + $num; #增加一行
- $arr[$i] = $y + "`r`n" + $arr[$i]; #重新赋值
- }
- break;
- }
- $s1 = $arr[$i];
- }
-
- $arr
复制代码
作者: meixi 时间: 2023-4-10 18:53
本帖最后由 meixi 于 2023-4-10 18:54 编辑
回复 21# WHY
多谢大佬,
那个垃圾软件肯定要用的, 现在找通用正则就是想让执行的速度快点, 它带的powershell可以直接用代码, 就是执行速度太慢了, 它处理一次要用六秒钟, 而用它自身的正则执行很快, 几乎是瞬间完成的
它也支持C#代码, 比PS快点 , 但还是有编译的过程, 也得要个几秒
作者: meixi 时间: 2023-4-10 18:56
回复 20# WHY
这个软件是主角, 它支持ps和C#都是为了增强它自身的功能, 但它本身是有正则模块的, 可能支持没有C#正则全
作者: WHY 时间: 2023-4-10 23:21
回复 22# meixi
有些软件就是这样的,这也想支持一下、那也想支持一下,万金油似的,有人认为挺好。
我倒是觉得,杂而不精,无异于什么都不支持,说它辣鸡并不为过。
不用找了,根本没有什么通用的正则!
如果有人告诉你:有!
这个人要么不懂正则,要么就是个江湖骗子。
作者: meixi 时间: 2023-4-11 10:01
回复 24# WHY
多谢大佬指导
我用最新的PCRE2版的DLL
用您的正则, 仍然会提示无效的替换值
PCRE2 Error Message: invalid replacement string
也就是说 $&[123]$1 字符串识别不了
C#的正则引擎, 确实独特, PHP7.3之后也是内置的PCRE2引擎
作者: meixi 时间: 2023-4-11 10:05
powershell确实好使, 但是执行效率, 真是不敢恭维
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |