Powershell: Replacing Regular Expressions with Variable Groups

Say I have a regular expression like the following, but I loaded it from a file into the $ regex variable and therefore have no idea about the development time, what is its contents, but at runtime I can find that it includes "version1" , "version2", "version3" and "version4":

"Version (?<version1>\d),(?<version2>\d),(?<version3>\d),(?<version4>\d)"

... and I have the following variables:

$version1 = "3"
$version2 = "2"
$version3 = "1"
$version4 = "0"

... and I find the following line in the file:

Version 7,7,0,0

... which is stored in the $ input variable, so ($ input -match $ regex) evaluates to $ true.

How to replace the named groups from $ regex in the $ input line with the values ​​$ version1, $ version2, $ version3, $ version4 if I don’t know the order in which they appear in $ regex (only I know that $ regex includes these named groups) ?

, , - ?

EDIT: - , ( 2, 3 4 ). , ( ):

#define SOME_MACRO(4, 1, 0, 0)

Version "1.2.3.4"

SomeStruct vs = { 99,99,99,99 }

, , , . , , , , .

-2: , , , , , , Powershell .

-3: , Ansgar , ( , , , ), "-replace" ( ) , . , - , . YMMV, . Ansgar .

:

  • $input - ,
  • $regex - ( [string]), , ,
  • $regexToGroupName - -, , , [regex]:: GetGroupNames(), ,
  • $groupNameToVersionNumber - -, .

$regex ( ), .

# This will give us the index and extent of each substring
# that we will be replacing (the parts that we will not keep)
$matchResults = ([regex]$regex).match($input)

# This will hold substrings from $input that were not captured
# by any of the supported named groups, as well as the replacement
# version strings, properly ordered, but will omit substrings captured
# by the named groups
$lineParts = @()
$startingIndex = 0
foreach ($groupName in $regexToGroupName.$regex)
{
    # Excise the substring leading up to the match for this group...
    $lineParts = $lineParts + $input.Substring($startingIndex, $matchResults.groups[$groupName].Index - $startingIndex)

    # Instead of the matched substring, we'll use the substitution
    $lineParts = $lineParts + $groupNameToVersionNumber.$groupName

    # Set the starting index of the next substring that we will keep...
    $startingIndex = $matchResults.groups[$groupName].Index + $matchResults.groups[$groupName].Length
}

# Keep the end of the original string (if there anything left)
$lineParts = $lineParts + $input.Substring($startingIndex, $input.Length - $startingIndex)

$newLine = ""
foreach ($part in $lineParts)
{
   $newLine = $newLine + $part
}
$input= $newLine
+5
2

, . , . ( , , ), , :

$oldver = $input -replace $regexp, '$1,$2,$3,$4'
$newver = $input -replace $oldver, "$Version1,$Version2,$Version3,$Version4"

Edit:

, .

$version = @($version1, $version2, $version3, $version4)
$input -match $regexp
$oldver = $regexp
$newver = $regexp
for ($i = 1; $i -le 4; $i++) {
  $oldver = $oldver -replace "\(\?<version$i>\\d\)", $matches["version$i"]
  $newver = $newver -replace "\(\?<version$i>\\d\)", $version[$i-1]
}
$input -replace $oldver, $newver
+4

, , - $input, :

$input -replace '(Version\s+)\d+,\d+,\d+,\d+',"`$1$Version1,$Version2,$Version3,$Version4"

PowerShell

, , . .

'dogcatcher' -replace '(?<pet>dog|cat)','I have a pet ${pet}.  '

:

I have a pet dog.  I have a pet cat.  cher

replace, . .. :

 'dogcatcher' -replace '(?<pet>dog|cat)|(?<singer>cher)','I have a pet ${pet}.  I like ${singer}' songs.  '

:

I have a pet dog.  I like  songs.  I have a pet cat.  I like  songs.  I have a pet .  I like cher songs.  

... , , .

, :

'dogcatcher' -replace '(?<pet>dog|cat)','I have a pet ${pet}.  ' -replace '(?<singer>cher)', 'I like ${singer}' songs.  ' 

... :

I have a pet dog.  I have a pet cat.  I like cher songs.  

, ; , , , . :

$input = 'I''m running Programmer' Notepad version 2.4.2.1440, and am a big fan.  I also have Chrome v    56.0.2924.87 (64-bit).' 

$version1 = 1
$version2 = 3
$version3 = 5
$version4 = 7

$v1Pattern = '(?<=\bv(?:ersion)?\s+)\d+(?=\.\d+\.\d+\.\d+)'
$v2Pattern = '(?<=\bv(?:ersion)?\s+\d+\.)\d+(?=\.\d+\.\d+)'
$v3Pattern = '(?<=\bv(?:ersion)?\s+\d+\.\d+\.)\d+(?=\.\d+)'
$v4Pattern = '(?<=\bv(?:ersion)?\s+\d+\.\d+\.\d+\.)\d+'

$input -replace $v1Pattern, $version1 -replace $v2Pattern, $version2 -replace $v3Pattern,$version3 -replace $v4Pattern,$version4

:

I'm running Programmer Notepad version 1.3.5.7, and am a big fan.  I also have Chrome v    1.3.5.7 (64-bit).

NB: 1 , , .

; , , . , , , " , ", " ".

: http://www.regular-expressions.info/lookaround.html

(, , , 4 :

$input = @'
#define SOME_MACRO(4, 1, 0, 0)

Version "1.2.3.4"

SomeStruct vs = { 99,99,99,99 }
'@

$version1 = 1
$version2 = 3
$version3 = 5
$version4 = 7

$v1Pattern = '(?<=\b)\d+(?=\s*[\.,]\s*\d+\s*[\.,]\s*\d+\s*[\.,]\s*\d+\b)'
$v2Pattern = '(?<=\b\d+\s*[\.,]\s*)\d+(?=\s*[\.,]\s*\d+\s*[\.,]\s*\d+\b)'
$v3Pattern = '(?<=\b\d+\s*[\.,]\s*\d+\s*[\.,]\s*)\d+(?=\s*[\.,]\s*\d+\b)'
$v4Pattern = '(?<=\b\d+\s*[\.,]\s*\d+\s*[\.,]\s*\d+\s*[\.,]\s*)\d+\b'

$input -replace $v1Pattern, $version1 -replace $v2Pattern, $version2 -replace $v3Pattern,$version3 -replace $v4Pattern,$version4

:

#define SOME_MACRO(1, 3, 5, 7)

Version "1.3.5.7"

SomeStruct vs = { 1,3,5,7 }
+1

All Articles