我有这个 html 代码。我想选择/删除注释之间的所有内容<!-- ARTICOL START -->
,并<!-- ARTICOL FINAL -->
保留所有这些<p class=..</p>
行。这可以用正则表达式完成吗?
<!-- ARTICOL START -->
<div align="justify">
<table width="682" border="0">
<tr>
<td><h1 class="den_articol" itemprop="sfe">My text here</h1></td>
</tr>
<tr>
<td class="text_dreapta">On Ianuarie 14, 2014, in <a href="https://neculaifantanaru.com/en/qualities-of-a-leader.html" title="See al articles from Qualities of a leader" class="external" rel="category tag">Qualities of a leader</a>, by Author</td>
</tr>
</table>
<h2 class="text_obisnuit2"><img src="index_files/sfa.jpg" width="718" height="605" id="sfs" usemap="#m_dgrnt" alt="hip" /><map name="tfAbonament" id="m_34">
<area shape="rect" coords="259,545,457,582" href="#plata" alt="" />
</map></h2>
<p class="den_articol">Why this text text?</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit2">test text text</p>
</div>
<p align="justify" class="text_obisnuit style3"> </p>
<!-- ARTICOL FINAL -->
输出应为:
<!-- ARTICOL START -->
<p class="den_articol">Why this text text?</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit2">test text text</p>
<!-- ARTICOL FINAL -->
我创建了一个正则表达式,但是不起作用:
寻找:(<\!-- ARTICOL START -->).*(?!<p class=.*</p>).*(<\!-- ARTICOL FINAL -->)
替换为:\1\2\3
此外,我相信这项任务可以通过电源外壳,无需使用正则表达式。如果有人知道更好的 PowerShell。但 powershell 必须修改来自 的所有 html 文件c:\Folder1
。
答案1
使用 Notepad++:
- Ctrl+H
- 找什么:
(?:\h*<!-- ARTICOL START -->\R|\G)\K(?:(<p class=.*?</p>\R?)|(?:(?!<p class=.*?</p>)[\s\S])+)(?=[\s\S]+<!-- ARTICOL FINAL -->)
- 用。。。来代替:
$1
- 查看 环绕
- 查看 正则表达式
- 取消选中
. matches newline
- Replace all
截图(之前):
截图(之后):
答案2
在 Powershell 中工作:
$sourcedir = "C:\Folder1\"
$resultsdir = "C:\Folder2\"
Get-ChildItem -Path $sourcedir -Filter *.html | ForEach-Object{
$output=@()
$content = Get-Content -Path $_.FullName
$start = $content | Where-Object {$_ -match '<!-- ARTICOL START -->'}
$final = $content | Where-Object {$_ -match '<!-- ARTICOL FINAL -->'}
for($i=0;$i -lt $content.Count;$i++){
if(($i -gt $content.IndexOf($start)) -and ($i -lt $content.IndexOf($final))){
if($content[$i] -notmatch '<p class='){
continue
}
}
$output += $content[$i]
}
$output | Out-File -FilePath $resultsdir\$($_.name)
}
谢谢你,薛建军-MSFT这对我的回答有帮助这里
答案3
好的,这是解析 html 文件的正则表达式方法,事实上这是一个非常糟糕的想法,我现在可以使用(更)复杂的 PowerShell 和 Python 3 代码来更正确地执行此操作,但您要求使用正则表达式方法,所以我只会给出您所要求的,因为您的 html 代码并不是那么复杂。
所以我将您的代码复制粘贴到 Notepad++ 中并将其保存为扩展名为 .html 的文本文件,我将其保存在 D:\test.html
<!-- ARTICOL START -->
<div align="justify">
<table width="682" border="0">
<tr>
<td><h1 class="den_articol" itemprop="sfe">My text here</h1></td>
</tr>
<tr>
<td class="text_dreapta">On Ianuarie 14, 2014, in <a href="https://neculaifantanaru.com/en/qualities-of-a-leader.html" title="See al articles from Qualities of a leader" class="external" rel="category tag">Qualities of a leader</a>, by Author</td>
</tr>
</table>
<h2 class="text_obisnuit2"><img src="index_files/sfa.jpg" width="718" height="605" id="sfs" usemap="#m_dgrnt" alt="hip" /><map name="tfAbonament" id="m_34">
<area shape="rect" coords="259,545,457,582" href="#plata" alt="" />
</map></h2>
<p class="den_articol">Why this text text?</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit2">test text text</p>
</div>
<p align="justify" class="text_obisnuit style3"> </p>
<!-- ARTICOL FINAL -->
下一步应该是从文件中获取内容,在 PowerShell 中这通常使用 来完成Get-Content
,然后只需将第一个 cmdlet 的结果通过管道传输到Where-Object
cmdlet 以使用正则表达式匹配过滤结果,如果语句为真则包含该行,否则不包含,这就是您过滤结果的方式,并且where
是 的别名where-object
。
get-content D:\test.html | where {$_ -match "ARTICOL|<P class=(.*)</p>"}
输出结果如下:
<!-- ARTICOL START -->
<td><h1 class="den_articol" itemprop="sfe">My text here</h1></td>
<p class="den_articol">Why this text text?</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit">test text text</p>
<p class="text_obisnuit2">test text text</p>
<!-- ARTICOL FINAL -->
我承认这并不完全是你想要的,但已经很接近了。
现在可以使用 for 循环和 if 语句的组合来实现相同的结果:
$html = get-content D:\test.html
for ($i = 0; $i -lt $html.count; $i++) {
if ($html[$i] -match "ARTICOL|<P class=(.*)</p>") { $html[$i] }
}
第一行获取文件的内容,默认情况下 get-content 逐行获取内容,因此结果是一个数组,我们将它保存在一个变量中,然后使用索引循环遍历数组,在 PowerShell 中,数组中第一个元素的索引为 0,因此最后一个元素的索引为数组中元素的数量减 1,我们逐个元素循环遍历数组并检查它是否与正则表达式匹配,如果匹配,则将其打印到屏幕上。
更新:要对一堆文件执行此操作,只需使用此代码(您必须替换占位符才能使用该代码):
$files = (Get-ChildItem -Path "path\to\folder" -Force -Recurse -filter *.html).FullName
foreach ($file in $files) {
$content = Get-Content -Path $file
$content = $content | where {$_ -match "ARTICOL|(<P class=(.*)</p>)"}
Set-Content -Path $file -Value $content
}