PowerShell 5与PowerShell 7中正则表达式匹配结果差异问题排查及疑问
问题核心:
[Environment]::NewLine的跨版本适配坑 你猜的没错,就是[Environment]::NewLine导致的差异!我来给你掰扯清楚背后的原因:
- 首先,从GitHub获取的这份Tor节点列表文本,换行符用的是LF(
\n)——这是网络传输和大多数Unix环境的标准换行格式。 - 而
[Environment]::NewLine是和操作系统绑定的:在Windows系统上它是CRLF(\r\n),在类Unix系统(包括跨平台运行的PowerShell 7)上是LF(\n)。哪怕是在Windows的PS7里,用CRLF去分割只有LF的文本,根本找不到匹配的分隔符,所以Split之后整个内容还是一个大字符串,后续的正则匹配自然完全失效(毕竟你是在匹配一整段文本,而不是单独的IP行)。
跨版本可靠解决方案
给你两个稳妥的解决办法,任选其一都能让PS5和PS7表现一致:
方法1:直接用LF换行符分割
既然网络文本基本都是LF换行,直接指定"``n"分割最直接:
$ipres = Invoke-WebRequest -Method GET -Uri 'https://raw.githubusercontent.com/SecOps-Institute/Tor-IP-Addresses/master/tor-exit-nodes.lst' $iplist = $ipres.Content.Split("`n") # 额外过滤空行,避免分割后出现空字符串元素 $iplist = $iplist | Where-Object { $_ -notmatch '^\s*$' } $iplist_v4 = $iplist | Where-Object { $_ -match '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$' } $iplist_v6 = $iplist | Where-Object { $_ -notmatch '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$' }
方法2:用PowerShell原生-split操作符(更推荐)
-split支持正则表达式,可以匹配所有常见的换行格式(CR、LF、CRLF),兼容性拉满:
$ipres = Invoke-WebRequest -Method GET -Uri 'https://raw.githubusercontent.com/SecOps-Institute/Tor-IP-Addresses/master/tor-exit-nodes.lst' # 匹配任意换行格式,完美适配所有场景 $iplist = $ipres.Content -split '\r?\n' $iplist = $iplist | Where-Object { $_ -notmatch '^\s*$' } $iplist_v4 = $iplist | Where-Object { $_ -match '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$' } $iplist_v6 = $iplist | Where-Object { $_ -notmatch '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$' }
总结一下
以后处理网络获取的文本时,尽量别依赖[Environment]::NewLine,因为它的行为跟着系统走,但网络文本的换行格式通常是统一的LF。用-split '\r?\n'是最省心的跨版本、跨平台方案,不管文本里是哪种换行,都能正确拆分。
内容的提问来源于stack exchange,提问作者Raymond A.
相关产品推荐
相关产品推荐

