Powershell -match“无法索引到空数组”

时间:2018-04-04 19:23:49

标签: regex xml string powershell pattern-matching

我有一个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 返回

4 个答案:

答案 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