我正在尝试使用正则表达式清理一些html文件(是的,我见过the post。我并不是一般地解析html),我想删除所有不包含标签的行。我的脚本如下:
Remove-Item $args[1]
$text = (Get-Content -Path $args[0] -Raw)
$text = $text -replace "^\s*\r?\n"
New-Item -Path $args[1] -ItemType File -Force -Value $text
有一堆其他的东西我想要替换,但我主要是尝试修复
我可以验证内部正则表达式是否正常工作: VSCode (它使用JS正则表达式,而不是powershell的.NET正则表达式)使用提供的正则表达式正确地匹配(并替换)有问题的行。
我知道这个Powershell is Special,所以我将Get-Content
的输出转换为一个嵌入了换行符的原始字符串。这并没有什么帮助。
我可以验证其他函数(即remove-item
和new-item
)是否正常工作,以及其他正则表达式是否正常工作,方法是将正则文本从"^\s*\r?\n"
更改为"p", "abc"
,并查看p
标记是否都变成了abc
标记。
此外,正则表达式\s*\r?\n
可以工作,因此并不是正则表达式找不到换行符。
正则表达式\A\s*\r?\n
也不起作用,这意味着它与PowerShell如何找到字符串的开始/结束位置有关。
到底怎么回事?
<p>This is some text</p>
(the next line has a bunch of spaces)
<p>this is some more text</p>
仅作为参考,当使用VSCode的JS regex引擎时,我的regex应该(并且确实)与上面示例的第二、第四和第五行匹配(我相信类似于PCRE)
最后,对正则表达式进行反编译:
^ from the start of the string
\s* match any number of whitespaces
\r? possibly followed by a carriage return
\n then a newline
发布于 2021-10-28 21:48:11
当你这样做的时候
$text = (Get-Content -Path $args[0] -Raw)
在$text
中有行结尾,您的正则表达式可以匹配它们。
^
锚点也可以匹配任何行的开头,但是,有一个特殊的标志要使用:
$text = $text -replace '(?m)^\s*\n'
\s
模式涵盖了回车,不需要担心它们,并使用\r?
。
说明
--------------------------------------------------------------------------------
(?m) set flags for this block (with ^ and $
matching start and end of line)
--------------------------------------------------------------------------------
^ the beginning of a "line"
--------------------------------------------------------------------------------
\s* whitespace (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
\n '\n' (newline)
发布于 2021-10-28 22:22:49
Ryszard Czech's helpful answer很好地解释了您的方法的问题,并提供了有效的解决方案。
从本质上讲,代码是希望从文件<>e210>中消除空或空白(全空白)行。
一种更简单但速度较慢的解决方案是利用Get-Content
的默认逐行流,并结合许多PowerShell运算符对输入数组进行操作的能力,在这种情况下,它们充当过滤器。
在这种情况下,您可以利用-match
operator (根据需要调整-Encoding
):
@(Get-Content -Path $args[0]) -match '\S' | Set-Content -Encoding UTF8 $args[1]
以上代码将文件$args[0]
中至少包含一个非空格字符(\S
)的所有行传递给Set-Content
,后者将过滤后的行保存到目标文件$args[1]
。
发布于 2021-10-28 21:39:48
诀窍是,您实际上不会有超过一行可以匹配。
当您使用-Raw
将文件转换为字符串时,您将其设置为一行。因此,^
将只匹配文件的开头,因为这是正则表达式引擎可以找到的唯一字符串开头标识符。
解决此问题的方法是匹配前一行末尾的换行符或匹配文件的开头,然后将其带入替换位置,如下所示:
$text = $text -replace "(^|\n)\s*\r?\n","$1"
https://stackoverflow.com/questions/69761254
复制相似问题