标题: [问题求助] PowerShell使用正则将多行文本中的键值整理出来 [打印本页]
作者: 小白龙 时间: 2022-11-20 10:34 标题: PowerShell使用正则将多行文本中的键值整理出来
我想把
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
键和值之前用 - 分开
键值对儿之间用 --- 分开
写了下面的代码, 遇到了正则匹配问题,
我的想法是用两个括号分别匹配住键和值的内容, 然后再整理, 但是括号就是匹配不上,
请路过大佬支招, 谢谢- $s = @'
- 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)
- '@
-
- $rx = [regex]'sss [A-Z]=\r\n(.+)\r\nsss [A-Z]v=(?s)(.+)?[A-Z]v.fff'
- $rx.Matches($s).Value
复制代码
作者: hfxiang 时间: 2022-11-20 12:20
将- 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)
复制代码
以ANSI格式保存为1.txt
将- /sss [^ ]=/ {
- A = substr($0, 1, 5) "v="
- B = substr($0, 5, 1) "v.fff"
- while ((getline) > 0) {
- if ($0 == B) {
- print "---"
- next
- }
- if ($0 == A) {
- print "-"
- } else {
- print
- }
- }
- }
复制代码
以ANSI格式保存为1.awk
下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )
执行- gawk -f.\1.awk 1.txt>2.txt
复制代码
结果(2.txt)- Key 1
- -
- Hello 1
- World 1
- ---
- Key 2
- -
- Hello 2
-
- World 2
- ---
- Key 3
- -
- Hello 3
- World 3
- ---
复制代码
作者: 小白龙 时间: 2022-11-20 14:16
回复 2# hfxiang
多谢大佬支招,
好像没有用正则, 这个exe能支持管道吗? 也就是要处理的文本不是在文件中获取
作者: xczxczxcz 时间: 2022-11-20 14:33
本帖最后由 xczxczxcz 于 2022-11-20 14:35 编辑
娱乐一下:- $s = @'
- 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)
- '@
-
- [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';
-
- 或
- ([regex]::Matches($s,"(?is)Key(?:(?!\r?\n?\w+v\.fff).)*").Value -join "`r`n---`r`n") -replace '(?m)(?:(?!v=).)*v=','-' -replace '(?m)^ +(\w+)','$1';
-
- 或 自己弄
复制代码
作者: 小白龙 时间: 2022-11-20 15:33
本帖最后由 小白龙 于 2022-11-20 15:37 编辑
回复 4# xczxczxcz
多谢大佬支招,
对正则有点晕, 有个情况忘提了,
处理前: 所有键的内容和值的内容的每行前都有一个空格,
处理后: 要删除所有键和值的内容的每行前的空格
现在下面键值内部的空行前面还是有个空格
sss Bv=
Hello 2
World 2
Bv.fff
作者: 小白龙 时间: 2022-11-20 16:52
回复 4# xczxczxcz
不好意思大佬, 我前面的描述太粗略了, 实际我想表达的是下面这个贴子的反向整理
http://www.bathome.net/thread-64359-1-1.html
作者: idwma 时间: 2022-11-20 18:19
正则非常通用呀,用多就会了- $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)^ +'
复制代码
作者: 小白龙 时间: 2022-11-20 18:32
回复 7# idwma
大佬666,
说实话, 您写的这正则, 我一看就晕了
作者: 小白龙 时间: 2022-11-20 18:34
本帖最后由 小白龙 于 2022-11-20 18:47 编辑
回复 7# idwma
大佬请教一下
(?s)
这个是什么意思? 是单行模式吗? 我记得有的地方还说, 这是打开 .匹配空白符的模式
<a>
这个什么意思, 没见过
\k
是什么
我敢说, 没有几年功力, 真写不出您这正则, 真是看不懂
作者: idwma 时间: 2022-11-20 18:41
回复 9# 小白龙
文档里都有说明呀,看不懂的地方多搜点例子多看几个就会了- https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expression-language-quick-reference
复制代码
作者: 小白龙 时间: 2022-11-20 18:42
回复 4# xczxczxcz
大佬, 能请教一下吗? 下面这两行什么意思, 我powershell官网搜索也没有找到, 只有(?m) (?s)
(?sm)
(?is)
作者: 小白龙 时间: 2022-11-20 18:44
回复 10# idwma
多谢大侠的链接, 以前在PS官网真没找到这么细的资料
作者: 小白龙 时间: 2022-11-21 20:02
本帖最后由 小白龙 于 2022-11-21 20:34 编辑
回复 7# idwma
大佬你好, 看了正则的资料后, 对(?s)还是搞不懂, 按理说, 它是放在正则前面的, 表示单行模式,
但是下面的例子中, 它是放在中间的,很少有资料介绍到这种情况
零星的资料解释说, 这是让.能匹配到\s空字符了
更搞不明白的是, 4楼的大佬, 正则的开头出现了(?sm) 这是什么意思, 单行和多行模式还能混在一起玩吗?- $s = @'
- public static
- {
- #if A
- part1
- #endif
-
- part
- part
-
- #if V
- part2
- #endif
-
- part
- part
-
- #if C
- part3
- #endif
- }
- '@
-
- $rx = [regex]'#if.*(?s)(.*?)#endif'
- $rx.Matches($s) |
- %{
- $_.Groups[1].Value
- }
复制代码
作者: idwma 时间: 2022-11-22 17:08
回复 13# 小白龙
正则用法灵活呀,不用过于纠结合不合理
作者: 小白龙 时间: 2022-11-22 18:27
回复 7# idwma
大佬, 不用 (\k<a>) 这个方法可以实现吗? 这个正则我在另一个软件中, 它不支持这个特性, 只支持 $1 $2 这种数字格式
作者: idwma 时间: 2022-11-22 18:56
回复 15# 小白龙 - $s -replace '(?s)sss (.)=\s*(.+)\s*sss \1v=\s*(.+)\s*\1v.fff\s*',"`$2-`r`n`$3---`r`n" -replace '(?s)\s*---\s*sss kv=.+|(?m)^ +'
复制代码
作者: 小白龙 时间: 2022-11-22 19:59
回复 16# idwma
感谢大佬, 正则水平太6了
作者: hfxiang 时间: 2022-11-22 20:03
回复 3# 小白龙
调用示例- for /f "tokens=*" %%a in ('gawk -f.\1.awk 1.txt') do @echo;%%a
复制代码
作者: 小白龙 时间: 2022-11-22 20:05
回复 18# hfxiang
感谢大佬,
我的意思是, 要处理的字符串, 是前面管道来的, 想直接处理, 不想存成文件再处理
作者: hfxiang 时间: 2022-11-22 20:38
回复 19# 小白龙
俺不知道你前面的exe文件是什么应用,下面用type做示例:- for /f "tokens=*" %%a in ('type 1.txt^|gawk -f.\1.awk') do @echo;%%a
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |