标题: [问题求助] 用Powershell 正则替换标签内容 [打印本页]
作者: 5i365 时间: 2022-6-1 17:36 标题: 用Powershell 正则替换标签内容
我想把下面红色字部分,替换为 <abc> 使用下面代码中的正则,会删掉粉色字的部分, 求路过高手指引, 提前感谢!
(gc 0.txt) -replace '(?s)(?<=<div id="topic_panel.*?>).*(?=</div>)', '<abc>' | Out-File ok.txt
-----------------------------------------------------------------------------------------------0.txt
<div id="topic_panel" style="display: none">
<div class="p_div"><p>Insert</p></div>
<ul>
<li id="sub-topic" class="submenu_btn"><span>A</label></span></li>
</ul>
</div>
</div>
<div id="transform_panel" style="display: none">
<ul>
<li id="clear_transform" class="submenu_btn" data-action="reset"><span>Reset Rotation/Skew</span></li>
<li id="rotate_left" class="submenu_btn" data-action="rotate-left"><span>Rotate Left</span></li>
<li id="rotate_right" class="submenu_btn" data-action="rotate-right"><span>Rotate Right</span></li>
<li id="skew_left" class="submenu_btn" data-action="skew-left"><span>Skew Left</span></li>
<li id="skew_right" class="submenu_btn" data-action="skew-right"><span>Skew Right</span></li>
</ul>
</div>
作者: flashercs 时间: 2022-6-2 07:25
本帖最后由 flashercs 于 2022-6-2 21:06 编辑
- function Get-AngleNode {
- [CmdletBinding()]
- [OutputType('System.Text.RegularExpressions.Match')]
- param(
- [Parameter(Mandatory = $true)]
- [string]$Html,
- # MUST like "<(?<openTag>[\w.:-]+)[^>]*>"
- [Parameter(mandatory = $true)]
- [regex]$ReAngle,
- # To find all nodes
- [switch]$FindAll
- )
- $startPosition = 0
- $reTag = [regex]'</(?<closeTag>[\w.:-]+)>|<(?<openTag>[\w.:-]+)[^>]*>'
- $stackTag = New-Object 'System.Collections.Generic.Stack[string]'
- do {
- $m = $ReAngle.Match($Html, $startPosition)
- if ($m.Success) {
- $m #openTag
- $stackTag.Push($m.Groups['openTag'].Value)
- $startPosition = $m.Index + $m.Length
- while ($true) {
- $m = $reTag.Match($Html, $startPosition)
- if (-not $m.Success) { break }
- $startPosition = $m.Index + $m.Length
- if ($m.Groups['openTag'].Success) {
- $stackTag.Push($m.Groups['openTag'].Value)
- } elseif ($stackTag.Peek() -eq $m.Groups['closeTag'].Value) {
- $null = $stackTag.Pop()
- if ($stackTag.Count -eq 0) {
- $m #clostTag
- break
- }
- } else { $PSCmdlet.WriteWarning("html parsing error: Index=$($m.Groups['closeTag'].Index),Value=$m") }
- }
- } else { break }
- }while ($FindAll)
- }
- function Edit-HtmlNode {
- [CmdletBinding()]
- [OutputType('string')]
- param(
- [Parameter(Mandatory = $true)]
- [string]$Html,
- [Parameter(Mandatory = $true)]
- [System.Collections.IDictionary]$DicNode
- )
- $strb = New-Object System.Text.StringBuilder
- $newhtml = $Html
- foreach ($key in $DicNode.Keys) {
- $null = $strb.Clear()
- $arrM = Get-AngleNode -Html $newhtml -ReAngle $key -FindAll
- $index = 0
- foreach ($m in $arrM) {
- if ($m.Groups['openTag'].Success) {
- $null = $strb.Append($newhtml, $index, $m.Index + $m.Length - $index)
- } else {
- $null = $strb.Append($DicNode[$key]).Append($m.Value)
- }
- $index = $m.Index + $m.Length
- }
- $null = $strb.Append($newhtml.Substring($index))
- $newhtml = $strb.ToString()
- }
- $newhtml
- }
- # region config
- $html = @"
- <div>
- <div id="topic_panel" style="display: none">
- <div class="p_div"><p>Insert</p></div>
- <ul>
- <li id="sub-topic" class="submenu_btn"><span>A</label></span></li>
- </ul>
- </div>
- </div>
- <h1 id="to_cd">-------------------------------------</h1>
- <div id="transform_panel" style="display: none">
- <ul>
- <li id="clear_transform" class="submenu_btn" data-action="reset"><span>Reset Rotation/Skew</span></li>
- <li id="rotate_left" class="submenu_btn" data-action="rotate-left"><span>Rotate Left</span></li>
- <li id="rotate_right" class="submenu_btn" data-action="rotate-right"><span>Rotate Right</span></li>
- <li id="skew_left" class="submenu_btn" data-action="skew-left"><span>Skew Left</span></li>
- <li id="skew_right" class="submenu_btn" data-action="skew-right"><span>Skew Right</span></li>
- </ul>
- <div id="top_ab" class="p_div"><p>Insert</p></div>
- </div>
- "@
-
- $htNode = @{
- '(?i)<(?<openTag>div) id="topic_panel"[^>]*>' = '<abc>text</abc>'
- '(?i)<(?<openTag>div) id="top_ab"[^>]*>' = '<a>tet</a>'
- '(?i)<(?<openTag>H1) id="to_cd"[^>]*>' = '<b>xt</b>'
- }
- $newhtml = Edit-HtmlNode -Html $html -DicNode $htNode
- $newhtml
复制代码
作者: 5i365 时间: 2022-6-2 09:14
本帖最后由 5i365 于 2022-6-2 09:34 编辑
回复 2# flashercs
可以得到正常的输出, 非常感谢大侠指引!
当需要查找的标签有N个, 分别替换成不同内容, 代码需要怎样更改? 实在看不懂代码含义 例如有3个需要查找和替换的标签及内容, 写在了下面的Hash中了
@{
'div id="topic_panel"' = '<abc>text</abc>'
'div id="top_ab"' = '<a>tet</a>'
'H1 id="to_cd"' = '<b>xt</b>'
}
看来直接正则替换的方法行不通了...
作者: idwma 时间: 2022-6-2 10:57
突然看懂了那个正则闭合标签的例子- (gc 0.txt) -join "`n" -replace '(?s)(<(?<HtmlTag>div) id=\"topic_panel.*?>)((?<Nested><\k<HtmlTag>[^>]*>)|</\k<HtmlTag>>(?<-Nested>)|.*?)*(</\k<HtmlTag>>)','$1<abc>$3'
复制代码
作者: flashercs 时间: 2022-6-2 21:10
本帖最后由 flashercs 于 2022-6-4 20:02 编辑
回复 4# idwma
感谢分享,我不知道.NET正则支持递归查询,还傻傻地自己造轮子.- function Edit-HtmlNode {
- [CmdletBinding()]
- [OutputType('string')]
- param(
- [Parameter(Mandatory = $true)]
- [string]$Html,
- [Parameter(Mandatory = $true)]
- [System.Collections.IDictionary]$DicNode
- )
- $dic = New-Object 'System.Collections.Generic.Dictionary[string,string]'
- foreach ($key in $DicNode.Keys) {
- $dic[$key + '(?is)[^<>]*(?>(?>(?:<!--.*?-->|<script[^>]*>.*?</script>|<input[^>]*>|<br[^>]*>|<img[^>]*>|<link[^>]*>|<meta[^>]*>|<!DOCTYPE[^>]*>|(?<node><(?<nodeName>[\w.:-]+)[^>]*>))[^<>]*)+(?>(?<-node></(?<-nodeName>\k<nodeName>)>)[^<>]*)*)*(</\k<openTag>>)'] = $DicNode[$key]
- }
- $newhtml = $Html
- foreach ($key in $dic.Keys) {
- $newhtml = $newhtml -replace $key, ('${1}' + $dic[$key] + '${2}')
- }
- $newhtml
- }
- # region config
- $html = Get-Content -LiteralPath $PSScriptRoot\test1.html -Raw -Encoding UTF8
- # endregion
- $htNode = @{
- '(?is)(<(?<openTag>div) id="topic_panel"[^>]*>)' = '1'
- '(?is)(<(?<openTag>div) id="top_ab"[^>]*>)' = '<a>tet</a>'
- '(?is)(<(?<openTag>H1) id="to_cd"[^>]*>)' = '<b>xt</b>'
- '(?is)(<(?<openTag>div) id="topic_shapes_panel"[^>]*>)' = ''
- }
- $newhtml = Edit-HtmlNode -Html $html -DicNode $htNode
- $newhtml
复制代码
作者: 5i365 时间: 2022-6-2 22:32
本帖最后由 5i365 于 2022-6-2 22:34 编辑
回复 5# flashercs
试了几个文件, 发现两个小问题1.对下图结构的标签, 不能完整替换, 我想将粉框中的内容替换为空 '(?is)(<(?<openTag>div) id="topic_shapes_panel"[^>]*>)' = ''
2.如果替换为数字,例如1 好像把所有的都删了 '(?is)(<(?<openTag>div) id="topic_panel"[^>]*>)' = '1'
作者: flashercs 时间: 2022-6-2 22:49
本帖最后由 flashercs 于 2022-6-2 22:59 编辑
回复 6# 5i365
看清了.目测 没问题的.可以把这部分html发出来看看
修改html 不太建议用正则,可以使用.NET库 htmlAgility
作者: 5i365 时间: 2022-6-2 23:08
本帖最后由 5i365 于 2022-6-2 23:14 编辑
回复 7# flashercs
感谢大侠回复,
我是用下面方法加载的html, 不加-raw好像没效果,
$html = gc 9.html -enc utf8 -raw
上面贴子图片的中的内容
https://send.cm/d/BrWp
作者: flashercs 时间: 2022-6-2 23:16
回复 8# 5i365
5楼代码改了一下; $html=gc $file -raw -enc utf8 对了,html是一个字符串;不是string[]
作者: 5i365 时间: 2022-6-2 23:29
回复 9# flashercs
奇怪, 这回替换没有动静了
作者: flashercs 时间: 2022-6-4 20:03
回复 10# 5i365
5楼 修改了一下.看看
作者: 5i365 时间: 2022-6-6 16:00
回复 11# flashercs
感谢大侠回复, 应该可以了!
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |