【问题标题】:Powershell Regex to match domain\usernamePowershell 正则表达式匹配域\用户名
【发布时间】:2012-08-09 20:54:37
【问题描述】:

我正在尝试创建一个正则表达式来匹配在 tomcat 服务器上发出请求的所有用户名。日志中的一行示例:

192.10.123.45 - 域/用户名 [30/Jul/2012:07:29:13 -0400] "GET /APP/ HTTP/1.1" 200 53167

问题是用户名有几种不同的格式:

  1. 用户名
  2. 域\用户名
  3. 域/用户名

当前尝试:

if(($line -match “GET”) -AND ($line -match "(\s-\s\w{1,})")) {
            $temp = $matches[0]
            if(($line -match “GET”) -AND ($line -match "(\s-\s\w{1,}\S)?=[\\\/](w{1,}\b)")) {
                $temp1 = $matches[0]
                Write-host $temp
            }

我在用户名之前使用空格作为起点,这似乎工作正常。我总是检查该行中是否包含“GET”,因为它是我们目前唯一关心的 PHP 调用。我有 2 个匹配项,因为第一个匹配项总是只匹配一个单词,如果第二个匹配项匹配,我将使用 $temp 修剪 $temp1,因为我们不关心域。我真正遇到的麻烦是如何用正则表达式说“反斜杠或正斜杠”。

另外,我不确定我的正则表达式是否处理用户名包含数字或域包含破折号的情况。我假设这是由 \w 拾取的,但我在开发中找不到任何我正在测试的案例。

对于我对正则表达式缺乏了解,我提前道歉。

【问题讨论】:

    标签: regex parsing tomcat powershell powershell-2.0


    【解决方案1】:

    如果我理解您的问题,您希望能够从字符串中提取域\用户名。以下几行将从您在示例中显示的用户名中提取用户名:

    $line = $line.split("-")[1]
    $line = $line.split("[")[0]
    $line = $line.trim()
    

    这将使$line 的值为domain/username

    现在,用于提取用户名。

    if ($line.Contains("/")) {
        $Line = $Line.split("/")[1]
    } #End if($line.Contains("/")) {
    if ($line.contains("\")) {
        $Line = $line.split("\")[1]
    } #End if ($line.contains("\")) {
    

    最终结果将是包含用户名的$line 这可以全部包含在对 GET 的搜索中

    if (($line -match “GET”) {
        $Line = $Line.Replace(" - "," < ") 
        #If there is a - in the username, this replaces it so the split doesn't break up the username.  Change the < to suit whatever works best
        $line = $line.split("<")[1]
        $line = $line.split("[")[0]
        $line = $line.trim()
        if ($line.Contains("/")) {
            $Line = $Line.split("/")[1]
        } #End if($line.Contains("/")) {
        if ($line.contains("\")) {
            $Line = $line.split("\")[1]
        } #End if ($line.contains("\")) {
    }#End if (($line -match “GET”) {
    

    我用你放在那里的线路进行了测试,我最终得到了 $line 等于 username

    在我回答了这个问题之后,我想你可能想要一个用于其他用途的正则表达式。所以我也写了如何用正则表达式来做到这一点:

    if([regex]::Match($Line,".*GET.*").Success) {
            $line = [regex]::Split($Line,".*\s[-]{1}\s")
            $Line = [regex]::Split($Line,"\s[\[].*")
        if ([regex]::Match($Line,"[\\]{1}|[//]{1}").Success) {
        $Line = [regex]::Split($Line,".*[//]|.*[\\]")
        } #End if ([regex]::Match($Line,"[\]{1}|[//]{1}").Success) {
    } #End if([regex]::Match($Line,".*GET.*").Success) {
    

    我再次对此进行了测试,它可以在我的环境中提取用户名。这些都不关心域或用户名中是否有- 或数字。

    【讨论】:

    • 嘿尼克,感谢您的帮助,这几乎解决了我所有的问题。我不会选择第一个解决方案,我没有测试它,因为我想使用正则表达式,我觉得它对于这些类型的事情可能更有用和更准确。第一个 if 语句正确处理用户名或域\用户名,第二个 if 语句从域名中解析用户名,仅用于案例域/用户名。这仍然使 case domain\username 未处理。我认为这可能只是您的拼写错误,您的 if 语句中有一个反斜杠,而 split 中有两个反斜杠。您能解释一下吗
    • 第二个 if 语句检查反斜杠或正斜杠。我测试了所有三个,它们都没有问题。正则表达式中的 a|b 表示 a 或 b。两个\的原因是为了逃避它。 / 不需要转义。
    • 是的,我使用了你的确切代码,但它没有工作,但我还是拿了你显示的 | (或)并使我的代码正常工作,所以谢谢。但我对正则表达式的了解足以理解您的写作内容。所以我的问题是。为什么在 if 语句中有两个正斜杠,而在反斜杠中没有使用转义符?这是我的第二个 if 语句,类似于你的,但我的工作 if(($line -match “GET”) -AND ($line -match "\s[-]{1}\s\w{1,}((\\|/)\w{1,}\b)")) { $temp = $matches[1]; $temp = $temp.TrimStart("\\|/"); }
    • 我在家里再次测试了它,它确实导致` being alone. All worked when I put it in with \`出现问题。我已经相应地修改了我的答案。我尝试了您的代码,但由于我不知道$matches 是如何被声明的,所以我什么也没有出来。希望这会有所帮助。
    • 啊抱歉,我不应该假设每个人都知道$matches 是什么。 $matches 包含与 -match 和 -not match 运算符一起使用的匹配词数组。有关更多信息,请在控制台中输入 get-help about_automatic_variables。我不确定它是否适用于您的[regex]::Match(),但我还没有测试过。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    相关资源
    最近更新 更多