gpt4 book ai didi

regex - Powershell正则表达式替换文件中的url

转载 作者:行者123 更新时间:2023-12-02 09:05:32 27 4
gpt4 key购买 nike

我正在尝试匹配正则表达式并替换文件中的匹配项。我的正则表达式如下(匹配良好):

$regex1 = [regex] "index.php\?title\=[a-zA-Z0-9_]*"

我尝试在其中运行替换的源文件的编辑摘录:

<content:encoded>
<![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<a href="http://[redacted]/index.php?title=User_Manual">The software</a>, running on the
<a href="http://[redacted]/index.php?title=Mobile_Device">POS Device</a>, enables
<a href="http://[redacted]/index.php?title=Logging_In">log in</a>,
<a href="http://[redacted]/index.php?title=Selecting_Journey">select a journey</a>

以及 Powershell 替代品:

.Replace("index.php?title=","").Replace("_","-").ToLower())

我已经提取了所有匹配项,将 $allmatches 数组转换为新数组(因此它将是可写的),然后更新新数组中的值。我无法弄清楚如何将其写回到文件中,并且似乎无法找到任何帖子或文档来帮助解决此问题。我迄今为止的代码:

$regex1 = [regex] "index.php\?title\=[a-zA-Z0-9_]*"

$contentOf=Get-Content $contentfile
$allmatches=$regex1.Matches($contentOf)
$totalcount=$allmatches.Count

$newArray = $allmatches | select *

for($i=0;$i -le $totalCount;$i++) {
$newvalue=(($allmatches[$i].Value).Replace("index.php?title=","").Replace("_","-").ToLower())
$newArray[$i].Value = $newvalue
}

此时我有一个数组 $newArray ,其中包含所有正则表达式匹配和替换,但不知道如何将其写回我的文件/变量,例如 $newarray[0]:

Groups   : {0}
Success : True
Name : 0
Captures : {0}
Index : 4931
Length : 40
Value : user-manual

当然,我的处理方式可能完全错误。至于我为什么选择 Powershell 来执行此操作,只是因为这是我这些天花大部分时间编写脚本的地方......当然我确信它可以在 shell 中实现(这只需要我更长的时间)到达那里)。

最佳答案

这实际上是在正则表达式和 .Net Substitutions in Regular Expressions 中使用捕获组的好地方。修改后的正则表达式为:

$regex = [regex] 'index\.php\?title\=(\p{L}*)_(\p{L}*)'
  • \p{L} 匹配任何字母(由 Unicode 定义,而不仅仅是 A-Z)。
  • (\p{L}*)是一个仅包含字母的编号捕获组。
  • 替换模式字符串将使用 $1$2 来引用每个捕获组:'$1-$2'。请注意,在替换字符串上使用单引号 '' 可以防止 $1$2 上的 PowerShell 变量扩展。

简单替换

如果我们只关心捕获组按原样,我们可以使用这个代码:

    $testContent = @'
<content:encoded>
<![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<a href="http://[redacted]/index.php?title=User_Manual">The software</a>, running on the
<a href="http://[redacted]/index.php?title=Mobile_Device">POS Device</a>, enables
<a href="http://[redacted]/index.php?title=Logging_In">log in</a>,
<a href="http://[redacted]/index.php?title=Selecting_Journey">select a journey</a>
'@
$regex = [regex] 'index\.php\?title\=(\p{L}*)_(\p{L}*)'
$modifiedContent = [regex]::Replace($testContent, $regex, '$1-$2')

结果是:

<content:encoded>
<![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<a href="http://[redacted]/index.php?title=User_Manual">The software</a>, running on the
<a href="http://[redacted]/index.php?title=Mobile_Device">POS Device</a>, enables
<a href="http://[redacted]/index.php?title=Logging_In">log in</a>,
<a href="http://[redacted]/index.php?title=Selecting_Journey">select a journey</a>

这种方法的问题是不允许我们将组更改为小写。正则表达式实际上没有办法处理这个要求。幸运的是,.Net 有一个扩展,可以让我们轻松处理更复杂的情况。

使用 MatchEvaluator 委托(delegate)

一个MatchEvaluator是一个对象,可与正则表达式替换方法的重载一起使用,以解决正常替换不足的情况。在 PowerShell 中,它们可以是带有 [Match] 参数的简单脚本 block :

    $testContent = @'
<content:encoded><![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<content:encoded>
<![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<a href="http://[redacted]/index.php?title=User_Manual">The software</a>, running on the
<a href="http://[redacted]/index.php?title=Mobile_Device">POS Device</a>, enables
<a href="http://[redacted]/index.php?title=Logging_In">log in</a>,
<a href="http://[redacted]/index.php?title=Selecting_Journey">select a journey</a>
'@
$regex = [regex] 'index\.php\?title\=(\p{L}*)_(\p{L}*)'
$MatchEvaluator = {
param($match)
$group1 = $match.Groups[1].Value.toLower()
$group2 = $match.Groups[2].Value.toLower()
return "$group1-$group2"
}
[regex]::Replace($testContent, $regex, $MatchEvaluator)

这给出了期望的结果:

<content:encoded>
<![CDATA[<a href="http://[redacted]/index.php?title=User_Manual">
<a href="http://[redacted]/index.php?title=User_Manual">The software</a>, running on the
<a href="http://[redacted]/index.php?title=Mobile_Device">POS Device</a>, enables
<a href="http://[redacted]/index.php?title=Logging_In">log in</a>,
<a href="http://[redacted]/index.php?title=Selecting_Journey">select a journey</a>

替换文件的内容

最终的代码如下所示:

# Load the file as a single string
$content = Get-Content $contentfile -Raw

# Regex to replace, with capturing groups
$regex = [regex] 'index\.php\?title\=(\p{L}*)_(\p{L}*)'

# Delegate to transfrom capture groups into lowercase
$MatchEvaluator = {
param($match)
$group1 = $match.Groups[1].Value.toLower()
$group2 = $match.Groups[2].Value.toLower()
return "$group1-$group2"
}

# Replace all matches of the regular expression with delegate
$modifiedContent = [regex]::Replace($Content, $regex, $MatchEvaluator)

# Overwrite existing file
$modifiedContent | Out-File $contentfile

关于regex - Powershell正则表达式替换文件中的url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58935570/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com