我有一个xml
文件,忽略开头的数字,这不属于它。
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<one>
(3)<x> </x>
(4)</one><look> HERE </look> <find> 123 </find> <some> </some>
(5)<two></two>
我知道有一行有<look> HERE </look>
标记,我希望能够找到位于<find>
标记内的值(在这种情况下{ {1}}),它位于同一行。
123
为什么呢?我希望得到Get-Content '.\x.xml' # works
$line = $x -match "<look> HERE </look>" # this returns the entire line (line 4 in this case)
$line -match "<find>(?<content>.*)</find>"
$matches['content'] #cannot index into a null array error
返回
答案 0 :(得分:2)
尝试以这种方式解析XML。 Powershell可以将字符串转换为XML对象,使用正则表达式解析XML的per my comment不是一个好主意。
$x = [xml]@"
<xml>
<one>
<x> </x>
</one><look> HERE </look> <find> 123 </find> <some> </some>
<two></two>
</xml>
"@
$x.xml.find
123
答案 1 :(得分:1)
回答关于原因的实际问题(无论你是否应该这样做。雅各布科尔文的答案提供了更好的方法。
使用boolean
时,单个字符串会返回$true
并返回$false
或-match
如果您使用Select-String
,则可以使用ForEach-Object { $_.matches.groups } | Where-Object {$_.name -match 'content'} | select -expand value
获取所需信息。
所以两个选项是:
$line | Where-Object {
$_ -match "<find>(?<content>.*)</find>"
} | ForEach-Object {
$matches['content']
}
# Or
$line | select-string "<find>(?<content>.*)</find>" | ForEach-Object {
$_.matches.groups
} | Where-Object {
$_.name -match "content"
} | Select -Expand value
答案 2 :(得分:1)
对集合应用-match
时,它始终返回一个集合。如果您查看$line
的类型,您会看到它的1个元素的数组:
> $line.GetType().FullName
System.Object[]
> $line.Count
1
在对集合进行匹配时,$matches
未设置,因为集合中可能存在多个匹配项。 $matches
仅用于标量匹配操作。由于$line
仍然是一个集合,为了完成这项工作,您需要在应用$line
之前将其编入索引-match
:
> $line[0] -match "<find>(?<content>.*)</find>"
True
现在匹配成功了标量值并设置content
:
> $matches['content']
123
答案 3 :(得分:0)
我有同样的错误,解决方案只是微不足道的。 我必须用“”包裹我的字符串。
我搜索了文件中的内容:
$content = (Get-Content filename.txt)
$content -match '.*(?<namedGroup>test)'
Write-Output $Matches.namedGroup
,我不得不将其更改为:
$content = (Get-Content filename.txt)
"$content" -match '.*(?<namedGroup>test)'
Write-Output $Matches.namedGroup