正则表达式匹配标签,跳过几个,然后再次匹配

时间:2014-10-28 16:49:08

标签: regex powershell

我的xml文件格式如下:

<User>
<FirstName>Foo Bar</FirstName>
<LastName>Blah</LastName>
<OtherStuff>...</OtherStuff>
<More>...</More>
<CompanyName>Foo</CompanyName>
<EmailAddress>bar@foo.com</EmailAddress>
</User>
<User>
...

我想阅读所有xml文件,创建为输出<FirstName>,<CompanyName>,<EmailAddress>,所以:

Foo Bar,Foo,bar@foo.com
Name,User2,user@email.com
FSds,Blah,blah@blah.com

我正在使用以下正则表达式

(?si)<FirstName>(.*?)</FirstName>.*?<CompanyName>(.*?)</CompanyName>\s*<EmailAddress>(.*?)</EmailAddress>'

但是,这也会返回FirstNameCompanyName

之间的所有内容

我做错了什么?

2 个答案:

答案 0 :(得分:4)

为什么不使用XML处理?

C:\PS> $xml = [xml]@'
>>> <Users>
>>> <User>
>>> <FirstName>Foo Bar</FirstName>
>>> <LastName>Blah</LastName>
>>> <OtherStuff>...</OtherStuff>
>>> <More>...</More>
>>> <CompanyName>Foo</CompanyName>
>>> <EmailAddress>bar@foo.com</EmailAddress>
>>> </User>
>>> </Users>
>>> '@
C:\PS> "$($xml.Users.User.FirstName), $($xml.Users.User.CompanyName), $($xml.Users.User.EmailAddress)"
Foo Bar, Foo, bar@foo.com

您没有显示完整的XML文档,因此我猜测顶层节点。您需要根据XML文档的结构进行调整。

答案 1 :(得分:0)

如果你用here-string构建它,我发现多行正则表达式会更容易:

$String = @'
<User>
<FirstName>Foo Bar</FirstName>
<LastName>Blah</LastName>
<OtherStuff>...</OtherStuff>
<More>...</More>
<CompanyName>Foo</CompanyName>
<EmailAddress>bar@foo.com</EmailAddress>
</User>
'@

$regex = @'
(?ms).+?<FirstName>(.+?)</FirstName>.*?
<CompanyName>(.+?)</CompanyName>.*?
<EmailAddress>(.+?)</EmailAddress>.+?
'@

$string -match $regex > $null
$matches[1..3] -join ','



Foo Bar,Foo,bar@foo.com

如果它是一个大文件并且您不想立即阅读它,则可以使用结束标记作为分隔符:

Get-Content xmlfile.xml -Delimiter '</User>' |
 foreach {
  if ($_ -match $regex)
   {$matches[1..3] -join ','
   }