正则表达式提取单词

时间:2018-03-19 16:26:15

标签: regex powershell

我正在尝试从一行文字中提取单个单词。据我了解,Powershell正则表达式几乎与PCRE相同(我有一种轻松测试PCRE的方法)。我有一个文件包含(除其他外)像... ...

ignore=thisline
username=symcbean
dontRead=thisEither

我希望获得与“用户名”相关联的值。

我知道'='的LHS将包含“username”,可选地由空格包围,RHS将包含我试图提取的值(可选地由空格包围)。我要找的字符串将匹配\ w +,因此:

(?<=username=)\w+ 

适用于没有额外空格的情况。但我似乎无法容纳可选的空白区域。为简洁起见,我只展示了在下面的'='之前尝试处理空格的情况:

(?<=username\s*=)\w+   - doesn't match with or without additional space
(?<=username\W+)\w+    - doesn't match with or without additional space
(?<=username[\s=]*)\w+ - doesn't match with or without additional space

但是在上面的每种情况下,后视零宽度断言中的组(/ username \ s * = /,/ username \ W + /,/ username [\ s =] * /)与相关部分相匹配字符串。

我希望获得单个值匹配(而不是数组)。

2 个答案:

答案 0 :(得分:4)

嗯,你可以使用正则表达式然后你会two problems.这就是我要这样做的方式:

# Notice the extra spaces
$initialText = ' username = wombat  '
$userName = $intialText.Split('=')[1].Trim()

以下是关键线的工作原理:

  • Split()方法接受字符串$initialText,并将其划分为数组,从而消除传递给拆分的字符(将其视为分隔符)。现在,您有一个数组@(' username ',' wombat ')
  • 然后取数组的第1个(零原点)元素([1])。这是' wombat '
  • 然后调用Trim()方法,该方法删除字符串开头和结尾处的所有空格 - 所以你现在有'wombat' ...
  • ...您指定给$userName

拆分仍然有效你只需要找到以用户名开头的行。话虽如此,这是一个正则表达式方法:

$initialText = ' username = wombat  '
$initialString -match '^.+=\W+(?<username>.+)\W+$'
$username = $matches.username

或者整个文件:

从提示符开始:

Get-Content C:\Path\To\Some\File.txt | %{if($_.trim().startswith('username')){$_ -match '^.+=\W?(?<username>.+)\W?$'; $username = $matches.username; $username}}

或者如果你在脚本中这样做:

$fileContents = Get-Content C:\Path\To\Some\File.txt
foreach($line in $fileContents){
  if($line.Trim().StartsWith('username')){
    $line -match '^.+=\W?(?<username>.+)\W?$'
    $userName = $matches.username
  }
}
$userName

答案 1 :(得分:1)

如果您在单个文件中查找多个用户名,这应该可以解决问题。它只会将所有值放入一个字符串数组中。指出的正则表达式应该拉出你想要的东西。

[regex]$username = "(?<=username\s*=\s*)\w+"
$usernames = @(Select-String -Path $file -Pattern $username -AllMatches | ForEach-Object {
    $_.Matches | ForEach-Object{
        $_.Value
    }
})

要解释一点Select-String命令行开关,当您使用-AllMatches开关时,它将返回一组匹配对象。在这些匹配对象内部是匹配,组,捕获等。因此,您必须执行Foreach-Object { $_.Matches然后在每个匹配对象内部有一个值属性,因此| Foreach-Object { $_.Value

如果每个文件只有一个用户名,则可以按文件执行此操作:

$text = get-content $file
[regex]$usernameReg = "(?<=username\s*=\s*)\w+"
$username = $usernameReg.Match($text).Value