如果字符串中有重复字符,则如何在字符串的第一个实例处将其删除

时间:2018-09-21 10:25:32

标签: regex powershell

我写了一个简单的脚本,它遍历xml文件,使用带有指定标记(url)的随机行,并剥离封装链接本身的所有内容:

$importPath = "C:\PATH\feed.xml"

# get links
$link = Select-String '<loc>' $importPath

$count = 20

# randomize
$link = Get-Random -InputObject $link  -Count $count 

#strip
$link1 = $link -replace ".*<loc>" -replace "</loc>"

$rez = $link1 -join("`n") 

Write-Host $rez -ForegroundColor Green

这有效。但是,我想知道是否有任何方法可以改进此部分,因此我不必为每个供稿手动调整它:

$link1 = $link -replace ".*<loc>" -replace "</loc>"

由于标签名称的名称和长度可以不同,所以我认为我可以只使用标签括号(因为这在每个提要中都是一个常数)来指示从哪里开始修剪。

$link1 = $link -replace ".*<" -replace "<.*"

显然这是行不通的,因为没有区别应将哪个括号视为第一个括号,将哪个括号视为第二个括号。

例如:

<tagnamethatvaries>https://somesite.com/somepath</tagnamethatvaries>

如果我使用

$link1 = $link -replace ".*<" -replace "<.*" 

我得到

/tagnamethatvaries>

有什么方法可以为长度不同的字符串中的相同字符声明点?

3 个答案:

答案 0 :(得分:0)

由于我的声誉不够高,我无法发表评论以获取更多信息。

请参见下面的内容,如果您尝试根据第二次出现字符的位置来修剪字符串的末尾,则可以使用substring和indexof来完成。

请参见以下内容:

$link = "<tagnamethatvaries>https://somesite.com/somepath</tagnamethatvaries>"
$link1 = $link.Substring(0, $link.IndexOf("<",2))

这给出了以下结果:

<tagnamethatvaries>https://somesite.com/somepath

这将删除第一个标签

$link = "<tagnamethatvaries>https://somesite.com/somepath</tagnamethatvaries>"
$link1 = $link.Substring(($link.IndexOf(">",1)+1),($link.IndexOf("<",2))+1)

结果是

https://somesite.com/somepath</tagnamethatvaries>

希望这会有所帮助。

答案 1 :(得分:0)

看起来您正在尝试在XML标签之间获取内容。
通过使用正则表达式match and capture groups

,有一种更简单的方法来实现此目的

假设$feed是您的feed.xml内容,并运行以下脚本:

$feed = @(
"<foo>foo-link1</foo>"
"<bar>bar-link2</bar>")

foreach ($link in $feed) { 
    if ($link -match "<.*>(.*)<.*>") { 
        Write-Host $Matches[1] 
    } 
}

将写到您的控制台:

foo-link1
bar-link2

您还可以扩展功能以仅捕获您感兴趣的标签。

$feed = @(
"<foo>foo-link1</foo>"
"<bar>bar-link2</bar>")

$tagsToFind = @(
"foo"
"bar"
)

foreach ($link in $feed) { 
    foreach ($tag in $tagsToFind){
        if ($link -match "<$tag>(.*)</$tag>") { 
            Write-Host $Matches[1] 
        } 
    }
}

答案 2 :(得分:0)

通常为better use XML tools to work with xml files

如果您仍然需要,我可以使用带有look aroundsback reference的RegEx来匹配相同的标签名称,而在/之间使用{{1} },它已经提取了纯链接:

Select-String

位置:

Select-String  "C:\PATH\feed.xml" -Pattern '(?<=<([^>]+>))(http[^<]+)(?=</\1)' | 
    ForEach-Object {$_.Matches.Groups[2].Value} | Get-Random -Count 20

(?<=<([^>]+>)) 后面与正面(?<=匹配的肯定外观,其后跟至少一个/尽可能多的非<字符,并用括号括起来形成第一个捕获组稍后用作后向引用>

\1

捕获从(http[^<]+) 开始并在结束标记之前结束的链接。

http

(?=</\1) 和第一个捕获组中的标签名称开头的(?=是正面评价。

使用</遍历sls的matchs集合,并将其简化为第二个捕获组的链接