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

[问题求助] PowerShell使用正则将多行文本中的键值整理出来

[复制链接]
发表于 2022-11-20 10:34:48 | 显示全部楼层 |阅读模式
我想把
sss A=
Key 1
sss Av=
Hello 1
World 1

Av.fff

sss B=
Key 2
sss Bv=
Hello 2

World 2

Bv.fff

sss C=
Key 3
sss Cv=
Hello 3
World 3

Cv.fff

sss kv=
@
{A}={Av}
{B}={Bv}
{C}={Cv}
DDD(kv)

把上面的红色字整理出去,红色字内容是变化的, 但是它所在的位置不变,
整理为:
Key 1
-
Hello 1
World 1
---
Key 2
-
Hello 2

World 2
---
Key 3
-
Hello 3
World 3


键和值之前用 - 分开
键值对儿之间用 --- 分开

写了下面的代码, 遇到了正则匹配问题,

我的想法是用两个括号分别匹配住键和值的内容, 然后再整理, 但是括号就是匹配不上,

请路过大佬支招, 谢谢
  1. $s = @'
  2. sss A=
  3. Key 1
  4. sss Av=
  5. Hello 1
  6. World 1
  7. Av.fff

  8. sss B=
  9. Key 2
  10. sss Bv=
  11. Hello 2

  12. World 2
  13. Bv.fff

  14. sss C=
  15. Key 3
  16. sss Cv=
  17. Hello 3
  18. World 3
  19. Cv.fff

  20. sss kv=
  21. @
  22. {A}={Av}
  23. {B}={Bv}
  24. {C}={Cv}
  25. DDD(kv)
  26. '@

  27. $rx = [regex]'sss [A-Z]=\r\n(.+)\r\nsss [A-Z]v=(?s)(.+)?[A-Z]v.fff'
  28. $rx.Matches($s).Value
复制代码
发表于 2022-11-20 12:20:07 | 显示全部楼层

  1. sss A=
  2. Key 1
  3. sss Av=
  4. Hello 1
  5. World 1
  6. Av.fff

  7. sss B=
  8. Key 2
  9. sss Bv=
  10. Hello 2

  11. World 2
  12. Bv.fff

  13. sss C=
  14. Key 3
  15. sss Cv=
  16. Hello 3
  17. World 3
  18. Cv.fff

  19. sss kv=
  20. @
  21. {A}={Av}
  22. {B}={Bv}
  23. {C}={Cv}
  24. DDD(kv)
复制代码
以ANSI格式保存为1.txt

  1. /sss [^ ]=/ {
  2.         A = substr($0, 1, 5) "v="
  3.         B = substr($0, 5, 1) "v.fff"
  4.         while ((getline) > 0) {
  5.                 if ($0 == B) {
  6.                         print "---"
  7.                         next
  8.                 }
  9.                 if ($0 == A) {
  10.                         print "-"
  11.                 } else {
  12.                         print
  13.                 }
  14.         }
  15. }
复制代码
以ANSI格式保存为1.awk
下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe
执行

  1. gawk -f.\1.awk 1.txt>2.txt
复制代码
结果(2.txt)

  1. Key 1
  2. -
  3. Hello 1
  4. World 1
  5. ---
  6. Key 2
  7. -
  8. Hello 2

  9. World 2
  10. ---
  11. Key 3
  12. -
  13. Hello 3
  14. World 3
  15. ---
复制代码

评分

参与人数 1技术 +1 收起 理由
小白龙 + 1 666

查看全部评分

 楼主| 发表于 2022-11-20 14:16:30 | 显示全部楼层
回复 2# hfxiang


    多谢大佬支招,

好像没有用正则, 这个exe能支持管道吗? 也就是要处理的文本不是在文件中获取
发表于 2022-11-20 14:33:17 | 显示全部楼层
本帖最后由 xczxczxcz 于 2022-11-20 14:35 编辑

娱乐一下:

  1. $s = @'
  2. sss A=
  3. Key 1
  4. sss Av=
  5. Hello 1
  6. World 1
  7. Av.fff

  8. sss B=
  9. Key 2
  10. sss Bv=
  11. Hello 2

  12. World 2
  13. Bv.fff

  14. sss C=
  15. Key 3
  16. sss Cv=
  17. Hello 3
  18. World 3
  19. Cv.fff

  20. sss kv=
  21. @
  22. {A}={Av}
  23. {B}={Bv}
  24. {C}={Cv}
  25. DDD(kv)
  26. '@

  27. [regex]::Replace($s, "(?sm)(?:(?!Key).)*Key\s*(\d+)(?:(?!\w+\s*\1).)*(?<m>(?:(?!\r?\n\s*\w+v\.fff).)*)","Key `$1`r`n-`r`n`${m}`r`n---`r`n") -replace '(?s)\r?\n?\s*(---)(?:(?!\1).)*$' -replace '(?m)^ +(\w+)','$1';


  28. ([regex]::Matches($s,"(?is)Key(?:(?!\r?\n?\w+v\.fff).)*").Value -join "`r`n---`r`n") -replace '(?m)(?:(?!v=).)*v=','-' -replace '(?m)^ +(\w+)','$1';

  29. 或 自己弄
复制代码

评分

参与人数 1技术 +1 收起 理由
小白龙 + 1 666

查看全部评分

 楼主| 发表于 2022-11-20 15:33:20 | 显示全部楼层
本帖最后由 小白龙 于 2022-11-20 15:37 编辑

回复 4# xczxczxcz


  多谢大佬支招,

对正则有点晕, 有个情况忘提了,
处理前: 所有键的内容和值的内容的每行前都有一个空格,
处理后: 要删除所有键和值的内容的每行前的空格

现在下面键值内部的空行前面还是有个空格

sss Bv=
Hello 2

World 2
Bv.fff
 楼主| 发表于 2022-11-20 16:52:23 | 显示全部楼层
回复 4# xczxczxcz


   不好意思大佬, 我前面的描述太粗略了, 实际我想表达的是下面这个贴子的反向整理

http://www.bathome.net/thread-64359-1-1.html
发表于 2022-11-20 18:19:35 | 显示全部楼层
正则非常通用呀,用多就会了
  1. $s -replace '(?s)sss (?<a>.)=\s*(.+)\s*sss (\k<a>)v=\s*(.+)\s*(\k<a>)v.fff\s*',"`$1-`r`n`$3---`r`n" -replace '(?s)\s*---\s*sss kv=.+|(?m)^ +'
复制代码

评分

参与人数 1技术 +1 收起 理由
小白龙 + 1 666

查看全部评分

 楼主| 发表于 2022-11-20 18:32:17 | 显示全部楼层
回复 7# idwma

大佬666,

说实话, 您写的这正则, 我一看就晕了
 楼主| 发表于 2022-11-20 18:34:47 | 显示全部楼层
本帖最后由 小白龙 于 2022-11-20 18:47 编辑

回复 7# idwma


大佬请教一下

(?s)
这个是什么意思? 是单行模式吗? 我记得有的地方还说, 这是打开 .匹配空白符的模式

<a>
这个什么意思, 没见过

\k
是什么

我敢说, 没有几年功力, 真写不出您这正则, 真是看不懂
发表于 2022-11-20 18:41:13 | 显示全部楼层
回复 9# 小白龙

文档里都有说明呀,看不懂的地方多搜点例子多看几个就会了
  1. https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expression-language-quick-reference
复制代码
 楼主| 发表于 2022-11-20 18:42:53 | 显示全部楼层
回复 4# xczxczxcz


   大佬,  能请教一下吗? 下面这两行什么意思, 我powershell官网搜索也没有找到, 只有(?m) (?s)

(?sm)

(?is)
 楼主| 发表于 2022-11-20 18:44:54 | 显示全部楼层
回复 10# idwma


   多谢大侠的链接, 以前在PS官网真没找到这么细的资料
 楼主| 发表于 2022-11-21 20:02:44 | 显示全部楼层
本帖最后由 小白龙 于 2022-11-21 20:34 编辑

回复 7# idwma


    大佬你好, 看了正则的资料后, 对(?s)还是搞不懂, 按理说, 它是放在正则前面的, 表示单行模式,

但是下面的例子中, 它是放在中间的,很少有资料介绍到这种情况

零星的资料解释说, 这是让.能匹配到\s空字符了
更搞不明白的是, 4楼的大佬, 正则的开头出现了(?sm) 这是什么意思, 单行和多行模式还能混在一起玩吗?
  1. $s = @'
  2. public static
  3. {
  4. #if A
  5.     part1
  6. #endif

  7. part
  8. part

  9. #if V
  10.     part2
  11. #endif

  12. part
  13. part

  14. #if C
  15.     part3
  16. #endif
  17. }
  18. '@

  19. $rx = [regex]'#if.*(?s)(.*?)#endif'
  20. $rx.Matches($s) |
  21. %{
  22.         $_.Groups[1].Value
  23. }
复制代码
发表于 2022-11-22 17:08:55 | 显示全部楼层
回复 13# 小白龙

正则用法灵活呀,不用过于纠结合不合理
 楼主| 发表于 2022-11-22 18:27:32 | 显示全部楼层
回复 7# idwma


  大佬, 不用 (\k<a>) 这个方法可以实现吗? 这个正则我在另一个软件中, 它不支持这个特性, 只支持 $1 $2 这种数字格式
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-17 05:27 , Processed in 0.014734 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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