简体   繁体   English

Powershell高级正则表达式可从文件中进行选择

[英]Powershell advanced regex to select from file

I would like to search for a pattern in a file which I can do easily with something like: 我想在文件中搜索一个模式,我可以通过以下方式轻松完成:

gc $filename | select-string $pattern

However once I have found this first pattern, using the location (line) of the first match as a starting point I would then like to start searching for a second pattern. 然而,一旦我找到了第一个模式,使用第一个匹配的位置(线)作为起点,我想开始搜索第二个模式。 Once the second pattern has been matched I would then like to return all lines between the first and second matches, discarding the matched lines themselves. 一旦第二个模式匹配,我就想返回第一个和第二个匹配之间的所有行,丢弃匹配的行本身。

Let's say your first pattern is pattern1 and the second pattern is pattern2 假设您的第一个模式是pattern1,第二个模式是pattern2

then expression would be (?<=pattern1)(.*?)(?=pattern2) 然后表达式将是(?<=pattern1)(.*?)(?=pattern2)

(?<=pattern1) - this will match prefix pattern but exclude it from capture (?<=pattern1) - 这将匹配前缀模式,但将其从捕获中排除
(?=pattern2) - this will match suffix pattern but exclude it from capture (?=pattern2) - 这将匹配后缀模式,但将其从捕获中排除

There may be a more elegant way but this will work 可能会有更优雅的方式,但这将有效

function ParseFile
{
    param([string] $FileName)
    $s = gc $FileName;
    for($x = 0 ;   $X -lt $s.count; $x++)
    {
        if(-not $first ){ 
            if($s[$x] -match "1000"){
                $first =$x
            }
        } 
        else{
            if($s[$x] -match "1075"){
                $second = $x ; 
                break;
            } 
       }

    }
    (($first +1) .. ($second -1))|%{
        $ret += $s[$_]
    }
    return $ret;
}

I've used foreach with $foreach.Movenext() : 我用$foreach.Movenext()使用了foreach

foreach ($line in (Get-Content $file))
{
    if ($line -match $firstTag)
    {
        do {
            $line
            $foreach.MoveNext()
        } until ($foreach.current -match $secondTag)
        continue
    }
}

This will simply return each line one by one, but you can do what you like within the do-loop if you need to process the result in some way 这将只是逐个返回每一行,但如果你需要以某种方式处理结果,你可以在do循环中做你喜欢的事情

Here is my one (a french bricolage ;o) ), imagine the file c:\\temp\\gorille.txt : 这是我的(法语拼写; o)),想象文件c:\\ temp \\ gorille.txt:

C'est à travers de larges grilles,
Que les femelles du canton,
Contemplaient un puissant gorille,
Sans souci du qu'en-dira-t-on.
Avec impudeur, ces commères
Lorgnaient même un endroit précis
Que, rigoureusement ma mère
M'a défendu de nommer ici...
Gare au gorille !...

Here is the text between "canton" and "endroit" 这是“canton”和“endroit”之间的文字

PS > (((Get-Content -Path C:\temp\gorille.txt) -join "£" | Select-String -Pattern "(?=canton)(.*)(?<=endroit)").matches[0].groups[0].value) -split "£"
canton,
Contemplaient un puissant gorille,
Sans souci du qu'en-dira-t-on.
Avec impudeur, ces commères
Lorgnaient même un endroit

I join all the lines with a special character "£" (choose onather one if used) then use @Alex Aza pattern in CmdLet Select-String then split again. 我使用特殊字符“£”加入所有行(如果使用则选择onather一个)然后在CmdLet Select-String中使用@Alex Aza模式然后再次拆分。

$start = select-string -Path $path -pattern $pattern1 -list |
  select -expand linenumber

$end = select-string -path $path -pattern $pattern2 |
  where-object {$_.linenumber -gt $start} |
  sort linenumber -desc |
  select -first 1 -expand linenumber

 (get-content $path)[$start..($end -2)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM