标题: [问题求助] 使用Powershell提取并处理标签 [打印本页]
作者: 小白龙 时间: 2022-8-29 18:38 标题: 使用Powershell提取并处理标签
本帖最后由 小白龙 于 2022-8-29 19:15 编辑
┋国家, 中国, 美国, 日本
┋城市, 北京, 上海, 广州
我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
┋称呼, 先生, 大姐, 女士
你好┃称呼┃别来无恙.
┋称呼, 先生, 大姐
你好┃称呼┃, 我的打印机品牌是┃品牌┃.
__________________________________________________________________________________________________
上面的内容中, 有一些文本标签, 需要分离出去, 手动操作完整步骤如下:
描述有点啰嗦,但是逻辑很清楚, 请路过的大佬帮助, 非常感谢:
下面自己写的代码, 已经分离出$B标签和$C内容, 但是标签出现的次数, 还有内容中的标签修改, 等一些细节没有实现
感觉难点在于: 内容要和其上方的标签结合起来修改, 还有就是标签出现次数的判断
第1行┋开头, 表示它是标签行, 标签文本是┋和第一个逗号间的文本, 即 国家 该行要分离出去,
格式变成 ┃Y_国家┃ 中国[]美国[]日本
第2行┋开头, 表示它是标签行, 标签文本是┋和第一个逗号间的文本, 即 城市 该行要分离出去,
格式变成 ┃Y_城市┃ 北京[]上海[]广州
第3行不是┋开头, 表示它是内容行, 注意: ┃XXX┃内的文本需要处理一下
┃名字┃里的文本 名字 因为不是内容行前面的标签文本, 所以改成┃N_名字┃
┃国家┃里的文本 国家 因为是内容行前面的, 第1行的标签文本, 所以改成┃Y_国家┃
┃年龄┃里的文本 年龄 因为不是内容行前面的标签文本, 所以改成┃N_年龄┃
┃城市┃里的文本 城市 因为是内容行前面的, 第2行的标签文本, 所以改成┃Y_城市┃
第4行是空行, 要保留, 不处理
第5行┋开头, 表示它是标签行, 标签文本是┋和第一个逗号间的文本, 即 称呼 该行要分离出去,
格式变成 ┃Y_称呼┃ 先生[]大姐[]女士
第6行不是┋开头, 表示它是内容行, 注意: ┃XXX┃内的文本需要处理一下
┃称呼┃里的文本 称呼 因为是内容行前面的, 第5行的标签文本, 所以改成┃Y_称呼┃
第7行是空行, 也要保留, 不处理
第8行┋开头, 表示它是标签行, 标签文本是┋和第一个逗号间的文本, 即 称呼 该行要分离出去,
格式变成 ┃Y_称呼2┃ 先生[]大姐
因为┃Y_称呼┃ 在前面已经出现过, 现在是第2次出现, 同理, 如果后面第3次出现, 要改为┃Y_称呼3┃ 以此类推
第9行不是┋开头, 表示它是内容行, 注意: ┃XXX┃内的文本需要处理一下
┃称呼┃里的文本 称呼 因为是内容行前面的, 第8行的标签文本, 所以改成┃Y_称呼2┃ 加序号2同上理
┃品牌┃里的文本 品牌 因为不是内容行前面的标签文本, 所以改成┃N_品牌┃
__________________________________________________________________________________________________
所有标签按顺序分离出来后, 存到变量$B, 值如下:
注意: 第2个┃后面只能有一个空格, 原来的 , 替换为[] 且[]两侧无空格
┃Y_国家┃ 中国[]美国[]日本
┃Y_城市┃ 北京[]上海[]广州
┃Y_称呼┃ 先生[]大姐[]女士
┃Y_称呼2┃ 先生[]大姐
__________________________________________________________________________________________________
所有余下的内容, 存到变量$C, 值如下:
注意: 内部的空行要保留
我的名字是 ┃N_名字┃, 我的国家是 ┃Y_国家┃, 我的年龄是┃N_年龄┃, 我家住在┃Y_城市┃!
你好┃Y_称呼┃别来无恙.
你好┃Y_称呼2┃, 我的打印机品牌是┃N_品牌┃.
- [Collections.ArrayList]$B = @() #存标签
- [Collections.ArrayList]$C = @() #存内容
-
- $A = @'
- ┋国家, 中国, 美国, 日本
- ┋城市, 北京, 上海, 广州
- 我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
-
- ┋称呼, 先生, 大姐, 女士
- 你好┃称呼┃别来无恙.
-
- ┋称呼, 先生, 大姐
- 你好┃称呼┃, 我的打印机品牌是┃品牌┃.
- '@
-
- #将变量$a的内容进行处理:
- #┋开头的标签行:分离、处理后保存到变量$B
- #余下的内容:处理后保存到变量$C
-
- $A -split '\r\n' |
- %{
- if ($_.StartsWith("┋"))
- {
- [void]$B.Add($_)
- }
- else
- {
- [void]$C.Add($_)
- }
- }
- $B -replace '┋(.*?),', '┃Y_${1}┃' -replace ',', '[]'
-
- $C
复制代码
作者: flashercs 时间: 2022-8-29 21:14
- [Collections.ArrayList]$B = @() #存标签
- [Collections.ArrayList]$C = @() #存内容
- $Script:dic=@{}
- $re=[regex]'┋(.*?),'
- $A = @'
- ┋国家, 中国, 美国, 日本
- ┋城市, 北京, 上海, 广州
- 我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
-
- ┋称呼, 先生, 大姐, 女士
- 你好┃称呼┃别来无恙.
-
- ┋称呼, 先生, 大姐
- 你好┃称呼┃, 我的打印机品牌是┃品牌┃.
- '@
-
- #将变量$a的内容进行处理:
- #┋开头的标签行:分离、处理后保存到变量$B
- #余下的内容:处理后保存到变量$C
-
- $A -split '\r\n' |
- %{
- if ($_.StartsWith("┋"))
- {
- [void]$B.Add(($re.Replace($_,{param($m)$k=$m.Groups[1].Value;if($Script:dic.ContainsKey($k)){"┃Y_$k$((++$Script:dic[$k]))┃"}else{$Script:dic[$k]=1;"┃Y_$k┃"}}) -replace ',\s*','[]'))
- }
- else
- {
- [void]$C.Add($_)
- }
- }
-
- $B
- #$B -replace '┋(.*?),', '┃Y_${1}┃' -replace ',', '[]'
-
- $C
复制代码
作者: 小白龙 时间: 2022-8-29 21:40
回复 2# flashercs
感谢大佬, 标签好像提取没问题了, 但是内容修改好像没有变动,
感谢大佬一直以来的帮助指导, 搞定后, 来杯咖啡
上面的最后的地方描述
__________________________________________________________________________________________________
所有余下的内容, 存到变量$C, 值如下:
注意: 内部的空行要保留
我的名字是 ┃N_名字┃, 我的国家是 ┃Y_国家┃, 我的年龄是┃N_年龄┃, 我家住在┃Y_城市┃!
你好┃Y_称呼┃别来无恙.
你好┃Y_称呼2┃, 我的打印机品牌是┃N_品牌┃.
作者: 小白龙 时间: 2022-8-29 21:57
手动操作的难度是要注意标签出现的次数,别的方面相对简单
感觉PS脚本最难的地方在, 内容里的标签修改, 要注意其上方的标签行, 再加上上边手动操作的难度
作者: flashercs 时间: 2022-8-29 23:12
本帖最后由 flashercs 于 2022-8-30 10:55 编辑
- [Collections.ArrayList]$B = @() #存标签
- [Collections.ArrayList]$C = @() #存内容
-
- $dicLabel = @{} #标签个数统计
- $dicLabelLocal = @{} #标签个数统计Local
- $reLabel = [regex]'┋([^,]*),(\s*)' #标签正则
- $reContent = [regex]'┃([^┃]*)┃' #内容正则
- # 替换label
- $sbLabel = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabel.ContainsKey($k)) {
- $ctr = (++$dicLabel[$k])
- $dicLabelLocal[$k] = "$k$ctr"
- "┃Y_$k$ctr┃$($m.Groups[2].Value)$k$ctr[]"
- } else {
- $dicLabel[$k] = 1
- $dicLabelLocal[$k] = "$k"
- "┃Y_$k┃ $($m.Groups[2].Value)$k[]"
- }
- }
- # 替换内容
- $sbContent = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelLocal.Contains($k)) {
- "┃Y_$($dicLabelLocal[$k])┃"
- } else {
- "┃N_$k┃"
- }
- }
- $A = @'
- ┋国家, 中国, 美国, 日本
- ┋城市, 北京, 上海, 广州
- 我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
-
- ┋称呼, 先生, 大姐, 女士
- 你好┃称呼┃别来无恙.
-
- ┋称呼, 先生, 大姐
- 你好┃称呼┃, 我的打印机品牌是┃品牌┃.
- '@
-
- #将变量$a的内容进行处理:
- #┋开头的标签行:分离、处理后保存到变量$B
- #余下的内容:处理后保存到变量$C
- $stack = 0 #content
- $A -split '\r\n' | ForEach-Object {
- if ($stack -eq 0) {
- if ($_.StartsWith("┋")) {
- $stack = 1
- $dicLabelLocal.Clear()
- [void]$B.Add(($reLabel.Replace($_, $sbLabel) -replace ',\s*', '[]'))
- } else {
- [void]$C.Add($reContent.Replace($_, $sbContent))
- }
- } else {
- if ($_.StartsWith("┋")) {
- [void]$B.Add(($reLabel.Replace($_, $sbLabel) -replace ',\s*', '[]'))
- } else {
- $stack = 0
- [void]$C.Add($reContent.Replace($_, $sbContent))
- }
- }
- }
-
- $B
- $C
复制代码
作者: 小白龙 时间: 2022-8-30 06:20
感谢大佬, 刚看到,
我再试试多行多段能否通过
作者: 小白龙 时间: 2022-8-30 09:11
本帖最后由 小白龙 于 2022-8-30 09:18 编辑
回复 5# flashercs
大佬,不好意思, 我在表达标签的格式时,漏了一句, PS代码我现在还看不懂, 麻烦大佬再改一下, 多谢
现在标签变量$B的值如下
┃Y_国家┃ 中国[]美国[]日本
┃Y_城市┃ 北京[]上海[]广州
┃Y_称呼┃ 先生[]大姐[]女士
┃Y_称呼2┃ 先生[]大姐
____________________________改为如下,就是在第2个┃之后的空格后面,加上 标签文本[]
┃Y_国家┃ 国家[]中国[]美国[]日本
┃Y_城市┃ 城市[]北京[]上海[]广州
┃Y_称呼┃ 称呼[]先生[]大姐[]女士
┃Y_称呼2┃ 称呼2[]先生[]大姐
作者: flashercs 时间: 2022-8-30 09:25
回复 7# 小白龙
上面修改了一下.
作者: 小白龙 时间: 2022-8-30 10:26
回复 8# flashercs
多谢大佬, 第2个┃和后面的文字之间有两个空格了, 应该只有一个
目标:
┃Y_国家┃ 国家[]
现状:
┃Y_国家┃ 国家[]
作者: flashercs 时间: 2022-8-30 10:58
第15行 空格
作者: 小白龙 时间: 2022-8-30 11:17
本帖最后由 小白龙 于 2022-8-30 11:22 编辑
回复 10# flashercs
大佬, 再给您加15红包, 麻烦给加个判断,
_________________________________________________________________
原来是这样:
┋国家, 中国, 美国, 日本
┋城市, 北京, 上海, 广州
我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
┋称呼, 先生, 大姐, 女士
你好┃称呼┃别来无恙.
┋称呼, 先生, 大姐
你好┃称呼┃, 我的打印机品牌是┃品牌┃.
_________________________________________________________________
现在是这样:
┋国家, 中国, 美国, 日本
┋大理, 三亚, 海南
我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
┋呼呼, 先生, 大姐, 女士
你好┃称呼┃别来无恙.
┋称呼, 先生, 大姐
你好┃称呼┃, 我的打印机品牌是┃品牌┃.
_________________________________________________________________
注意红色字部分, 虽然前面有┋ ,但是后面的文本 在其下方的内容中找不到匹配, 所以该行不再提取出去了, 其它的逻辑不变
简单的说: ┋标签文本, 和 其下方内容里的 ┃标签文本┃ 匹配时才分离出去, 否则就留下
最后的目标结果:
变量$B的值:
┃Y_国家┃ 国家[]中国[]美国[]日本
┃Y_称呼┃ 称呼[]先生[]大姐
变量$C的值:
┋大理, 三亚, 海南
我的名字是 ┃N_名字┃, 我的国家是 ┃Y_国家┃, 我的年龄是┃N_年龄┃, 我家住在┃N_城市┃!
┋呼呼, 先生, 大姐, 女士
你好┃N_称呼┃别来无恙.
你好┃Y_称呼┃, 我的打印机品牌是┃N_品牌┃.
作者: 小白龙 时间: 2022-8-30 11:34
回复 10# flashercs
另外, 也有可能像下面这样, 标签文本后没有,号, 也不提取出去了, 因为也匹配不到下面内容里的标签文本
┋呼呼先生大姐女士
作者: flashercs 时间: 2022-8-30 15:49
本帖最后由 flashercs 于 2022-8-30 15:52 编辑
回复 12# 小白龙
标签/内容 相互检测是太复杂- [Collections.ArrayList]$B = @() #存标签
- [Collections.ArrayList]$C = @() #存内容
-
- [Collections.ArrayList]$CLocal = @() #存内容Local
- [Collections.ArrayList]$keysInContent = @() #keys in content
- $dicLabelCtr = @{} #标签个数统计
- # $dicLabelLocal = @{} #标签个数统计: {称呼 =称呼2}
- $dicLabelLocal4B = [ordered]@{} #{标签 = Line}
- $reLabel = [regex]'┋([^,]*),(\s*)' #标签正则
- $reContent = [regex]'┃([^┃]*)┃' #内容正则
- # 替换label
- $sbLabel = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelCtr.ContainsKey($k)) {
- $ctr = (++$dicLabelCtr[$k])
- # $dicLabelLocal[$k] = "$k$ctr"
- "┃Y_$k$ctr┃$($m.Groups[2].Value)$k$ctr[]"
- } else {
- $dicLabelCtr[$k] = 1
- # $dicLabelLocal[$k] = "$k"
- "┃Y_$k┃$($m.Groups[2].Value)$k[]"
- }
- }
- # 替换内容
- $sbContent = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelLocal4B.Contains($k)) {
- [void]$keysInContent.Add($k)
- if ($dicLabelCtr.ContainsKey($k)) {
- "┃Y_${k}$($dicLabelCtr[$k]+1)┃"
- } else {
- "┃Y_${k}┃"
- }
- } else {
- "┃N_$k┃"
- }
- }
- $A = @'
- ┋国家, 中国, 美国, 日本
- ┋城市, 北京, 上海, 广州
- ┋大理, 三亚, 海南
- 我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
-
- ┋称呼, 先生, 大姐, 女士
- ┋呼呼, 先生, 大姐, 女士
- 你好┃称呼┃别来无恙.
-
- ┋称呼, 先生, 大姐
- 你好┃称呼┃, 我的打印机品牌是┃品牌┃.
- '@
-
- #将变量$a的内容进行处理:
- #┋开头的标签行:分离、处理后保存到变量$B
- #余下的内容:处理后保存到变量$C
- $stack = 0 #content
- $A -split '\r\n' | ForEach-Object {
- if ($stack -eq 0) {
- if ($_.StartsWith("┋")) {
- $stack = 1
- # procossing prev section
- for ($i = 0; $i -lt $CLocal.Count; $i++) {
- $CLocal[$i] = $reContent.Replace($CLocal[$i], $sbContent)
- }
- foreach ($key in @($dicLabelLocal4B.Keys)) {
- if (-not $keysInContent.Contains($key)) {
- [void]$C.Add($dicLabelLocal4B[$key])
- $dicLabelLocal4B.Remove($key)
- } else {
- [void]$B.Add(($reLabel.Replace($dicLabelLocal4B[$key], $sbLabel) -replace ',\s*', '[]'))
- }
- }
- [void]$C.AddRange($CLocal)
- $CLocal.Clear()
- $keysInContent.Clear()
- $dicLabelLocal4B.Clear()
- # next section
- $m = $reLabel.Match($_)
- if ($m.Success) {
- $dicLabelLocal4B[$m.Groups[1].Value] = $_
- } else {
- $dicLabelLocal4B[$_] = $_
- }
- } else {
- [void]$CLocal.Add($_)
- }
- } else {
- # stack=1
- if ($_.StartsWith("┋")) {
- $m = $reLabel.Match($_)
- if ($m.Success) {
- $dicLabelLocal4B[$m.Groups[1].Value] = $_
- } else {
- $dicLabelLocal4B[$_] = $_
- }
- } else {
- $stack = 0
- [void]$CLocal.Add($_)
- }
- }
- }
- # procossing prev section
- for ($i = 0; $i -lt $CLocal.Count; $i++) {
- $CLocal[$i] = $reContent.Replace($CLocal[$i], $sbContent)
- }
- foreach ($key in @($dicLabelLocal4B.Keys)) {
- if (-not $keysInContent.Contains($key)) {
- [void]$C.Add($dicLabelLocal4B[$key])
- $dicLabelLocal4B.Remove($key)
- } else {
- [void]$B.Add(($reLabel.Replace($dicLabelLocal4B[$key], $sbLabel) -replace ',\s*', '[]'))
- }
- }
- [void]$C.AddRange($CLocal)
- $CLocal.Clear()
- $keysInContent.Clear()
- $dicLabelLocal4B.Clear()
-
- $B
- $C
复制代码
作者: 小白龙 时间: 2022-8-30 16:41
回复 13# flashercs
感谢大佬, 一杯咖啡
我以为我最开始的描述就能实现标签的匹配, 后来发现不行, 然后才补上的, 辛苦了,
还没有过多测试, 不知道会不会出错,
作者: 小白龙 时间: 2022-8-30 16:46
现在代码, 实在是看不懂了,
还有更简单的算法吗? 或者用C#或模块什么的? 纯属学习交流
作者: 小白龙 时间: 2022-8-30 16:59
想用C#或库之类的, 是因为不知为什么, PS5在我的win10下启动好慢, 处理起来好像也比C#慢不少
要是C#我可以编译为一个exe, 速度会快很多
作者: flashercs 时间: 2022-8-30 18:01
文档格式算法是你定义的;我也看不懂;
powershell慢;因为加载module 太多;
这种自定义格式没有dll库可用, 你可以改成C#,只是有点麻烦;
作者: 小白龙 时间: 2022-8-30 18:33
感谢大佬提醒, 也没有外部module, 就是反应慢, 真是怪了
作者: 小白龙 时间: 2022-9-2 08:49
本帖最后由 小白龙 于 2022-9-2 08:52 编辑
回复 13# flashercs
原字符串:
┋国家, 中国, 美国, 日本
┋城市, 北京, 上海, 广州
┋大理, 三亚, 海南
我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
_________________________________________________________________
修改代码后处理结果:
┃Y_国家┃ 国家[]中国[]美国[]日本
┃Y_城市┃ 城市[]北京[]上海[]广州
┋大理, 三亚, 海南
我的名字是 ┃N_名字┃, 我的国家是 ┃Y_国家┃, 我的年龄是┃N_年龄┃, 我家住在┃Y_城市┃!
_________________________________________________________________
大佬, 请教两个小问题:
问题1.像上面的原字符串,标签前面带有空格符, 也能处理, PS代码我做了以下修改实现了:
行9
$reLabel = [regex]'┋([^,]*),(\s*)' #标签正则
改为
$reLabel = [regex]'\s*┋([^,]*),(\s*)' #标签正则
__________________
行60和90
$_.StartsWith("┋")
改为
$_.trim().StartsWith("┋")
___________________________________________________________
但是对应的C#代码, 我做了同样的修改, 会报错, 修改如下:
行21
Regex("┋([^,]*),(\\s*)"
改为了
Regex("\\s*┋([^,]*),(\\s*)"
__________________
行74和116
line.StartsWith("┋")
改为了
line.trim().StartsWith("┋")
问题2.处理后的标签┃后面必须要有一个空格, 但如果原字符串标签文本后的第一个逗号后面没有空格, 就不灵了, 例如下面:
┋国家,中国, 美国, 日本
作者: flashercs 时间: 2022-9-3 13:15
本帖最后由 flashercs 于 2022-9-3 13:21 编辑
.Trim() 必须大小写正确;
$reLabel = [regex]'\s*┋([^,]*),(\s*)' #标签正则- # 替换label
- $sbLabel = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelCtr.ContainsKey($k)) {
- $ctr = (++$dicLabelCtr[$k])
- "┃Y_$k$ctr┃ $k$ctr[]"
- } else {
- $dicLabelCtr[$k] = 1
- "┃Y_$k┃ $k[]"
- }
- }
复制代码
- //# 替换label
- MatchEvaluator sbLabel = delegate (Match m)
- {
- string k = m.Groups[1].Value;
- if (dicLabelCtr.ContainsKey(k))
- {
- int ctr = ++dicLabelCtr[k];
- return string.Format("┃Y_{0}{1}┃{2}{0}{1}[]", k, ctr, " ");
- }
- else
- {
- dicLabelCtr[k] = 1;
- return string.Format("┃Y_{0}┃{1}{0}[]", k, " ");
- }
- };
复制代码
作者: 小白龙 时间: 2022-9-3 17:44
回复 20# flashercs
多谢大佬!
作者: 小白龙 时间: 2022-9-3 20:48
回复 20# flashercs
大佬再请教一下,
标签前的符号, 前面的例子都是┋, 刚发现有时还可能会是┇ 还没有发现同时存在的情况,
我改了下面地方,想实现可以适用这两种符号, 结果标签输出为空:
$reLabel = [regex]'\s(┋|┇)([^,]*),(\s*)' #标签正则
和
if ($_.trim().StartsWith("┋") -or $_.trim().StartsWith("┇")) {
___________________________________________________________________- $A = @'
- ┇城市, 北京, 上海, 广州
- ┇大理, 三亚, 海南
- 我的名字是 ┃名字┃, 我的国家是 ┃国家┃, 我的年龄是┃年龄┃, 我家住在┃城市┃!
- '@
-
- [Collections.ArrayList]$B = @() #存标签
- [Collections.ArrayList]$C = @() #存内容
-
- [Collections.ArrayList]$CLocal = @() #存内容Local
- [Collections.ArrayList]$keysInContent = @() #keys in content
- $dicLabelCtr = @{} #标签个数统计
- # $dicLabelLocal = @{} #标签个数统计: {称呼 =称呼2}
- $dicLabelLocal4B = [ordered]@{} #{标签 = Line}
- #$reLabel = [regex]'┋([^,]*),(\s*)' #标签正则
- $reLabel = [regex]'\s(┋|┇)([^,]*),(\s*)' #标签正则
- $reContent = [regex]'┃([^┃]*)┃' #内容正则
- # 替换label
- $sbLabel = {
- param ([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelCtr.ContainsKey($k))
- {
- $ctr = (++$dicLabelCtr[$k])
- "┃Y_$k$ctr┃ $k$ctr[]"
- }
- else
- {
- $dicLabelCtr[$k] = 1
- "┃Y_$k┃ $k[]"
- }
- }
- # 替换内容
- $sbContent = {
- param([System.Text.RegularExpressions.Match]$m)
- $k = $m.Groups[1].Value
- if ($dicLabelLocal4B.Contains($k)) {
- [void]$keysInContent.Add($k)
- if ($dicLabelCtr.ContainsKey($k)) {
- "┃Y_${k}$($dicLabelCtr[$k]+1)┃"
- } else {
- "┃Y_${k}┃"
- }
- } else {
- "┃N_$k┃"
- }
- }
-
- $stack = 0 #content
- $A -split '\r\n' | ForEach-Object {
- if ($stack -eq 0) {
- if ($_.trim().StartsWith("┋") -or $_.trim().StartsWith("┇")) {
- $stack = 1
- # procossing prev section
- for ($i = 0; $i -lt $CLocal.Count; $i++) {
- $CLocal[$i] = $reContent.Replace($CLocal[$i], $sbContent)
- }
- foreach ($key in @($dicLabelLocal4B.Keys)) {
- if (-not $keysInContent.Contains($key)) {
- [void]$C.Add($dicLabelLocal4B[$key])
- $dicLabelLocal4B.Remove($key)
- } else {
- [void]$B.Add(($reLabel.Replace($dicLabelLocal4B[$key], $sbLabel) -replace ',\s*', '[]'))
- }
- }
- [void]$C.AddRange($CLocal)
- $CLocal.Clear()
- $keysInContent.Clear()
- $dicLabelLocal4B.Clear()
- # next section
- $m = $reLabel.Match($_)
- if ($m.Success) {
- $dicLabelLocal4B[$m.Groups[1].Value] = $_
- } else {
- $dicLabelLocal4B[$_] = $_
- }
- } else {
- [void]$CLocal.Add($_)
- }
- } else {
- # stack=1
- if ($_.trim().StartsWith("┋") -or $_.trim().StartsWith("┇")) {
- $m = $reLabel.Match($_)
- if ($m.Success) {
- $dicLabelLocal4B[$m.Groups[1].Value] = $_
- } else {
- $dicLabelLocal4B[$_] = $_
- }
- } else {
- $stack = 0
- [void]$CLocal.Add($_)
- }
- }
- }
- # procossing prev section
- for ($i = 0; $i -lt $CLocal.Count; $i++) {
- $CLocal[$i] = $reContent.Replace($CLocal[$i], $sbContent)
- }
- foreach ($key in @($dicLabelLocal4B.Keys)) {
- if (-not $keysInContent.Contains($key)) {
- [void]$C.Add($dicLabelLocal4B[$key])
- $dicLabelLocal4B.Remove($key)
- } else {
- [void]$B.Add(($reLabel.Replace($dicLabelLocal4B[$key], $sbLabel) -replace ',\s*', '[]'))
- }
- }
- [void]$C.AddRange($CLocal)
- $CLocal.Clear()
- $keysInContent.Clear()
- $dicLabelLocal4B.Clear()
-
- $B
- '---'
- $C
复制代码
作者: flashercs 时间: 2022-9-3 21:00
回复 22# 小白龙 - $reLabel = [regex]'\s*(?:┋|┇)([^,]*),(\s*)' #标签正则
复制代码
作者: 小白龙 时间: 2022-9-4 10:15
回复 23# flashercs
多谢
作者: xczxczxcz 时间: 2022-9-4 20:32
化简为繁!!!
powershell 吸取了 C#的对象方法和purl语言的文本高效处理方式,要想PS高效,文本处理尽量不要对象化。
给你支一招:把文本按需要的段落分割(不是逐行处理)。你这样的文本处理,十几万行也瞬间完成。 正则可以不单独入组的尽量不要入组,减少开销。能用贪婪的尽量贪婪。反正想办法减少回朔处理。
作者: 小白龙 时间: 2022-9-4 21:06
回复 25# xczxczxcz
感谢支招, 在下不才, 前面大佬写的PS和C#都还没有看懂
要是能分享一下代码就好了, 看看能不能懂,
感觉稳定是第一位的, 我前说的慢, 是因为我的系统PS启动慢, 处理速度还行
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |