programing

Powershell을 사용하여 정규 분포식 결과의 하위 섹션 교체

lovejava 2023. 10. 6. 20:48

Powershell을 사용하여 정규 분포식 결과의 하위 섹션 교체

파워셸을 사용하면 regex를 사용하여 복잡한 문자열을 파일에서 검색하고 다음 스니펫처럼 고정된 값으로 대체하는 방법을 알고 있습니다.

Get-ChildItem  "*.txt" |
Foreach-Object {
    $c = ($_ | Get-Content)
    $c = $c -replace $regexA,'NewText'
    [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
}

이제 저는 정규 경기의 각 경기의 서브섹션을 교체하는 방법을 알아보려고 합니다.이것이 위와 같이 매끄러운 단계로 이루어질 수 있습니까?아니면 더 큰 정규 표현식의 각각의 일치점을 추출하고, 그 안에서 검색하고 대체한 다음 어떻게든 그 결과를 원래 텍스트로 다시 연결해야 합니까?

예를 들어 설명하자면, 다음 테스트 텍스트에서 "TEST=*1404"와 같은 14xx 번호의 인스턴스만 찾고 14xx를 16xx로 대체하고자 한다고 가정합니다.

A 2180 1830 12 0 3 3 TEST=C1404
A 900 1830 12 0 3 3 TEST=R1413
A 400 1830 12 0 3 3 TEST=R1411
A 1090 1970 12 0 3 3 TEST=U1400
A 1090 1970 12 0 3 3 TEST=CSA1400
A 1090 1970 12 0 3 3 TEST=CSA1414
A 1090 1970 12 0 3 3 TEST=CSA140
A 1090 1970 12 0 3 3 TEST=CSA14001
A 1090 1970 12 0 3 3 TEST=CSA17001

즉, 결과 텍스트는 다음과 같으며, 여기서 처음 6행만 변경해야 합니다.

A 2180 1830 12 0 3 3 TEST=C1604
A 900 1830 12 0 3 3 TEST=R1613
A 400 1830 12 0 3 3 TEST=R1611
A 1090 1970 12 0 3 3 TEST=U1600
A 1090 1970 12 0 3 3 TEST=CSA1600
A 1090 1970 12 0 3 3 TEST=CSA1614 <- Second instance of '14' shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA140 <- Shorter numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA14001 <- Longer numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA17001

다음 regex는 교체해야 할 더 큰 문자열을 찾는 작업을 수행하는 것처럼 보이지만 파워셸에서 어떤 기능을 수행하는지 모르겠습니다(replace결과의 부분 문자열을 교체하는 데 사용합니다.그리고 도움이 된다면 언제든지 더 좋은 레지렉스를 추천해주세요.

$regexA = "\bTEST=\b[A-Za-z]+14\d\d\r"

'='와 숫자 사이에 있을 수 있는 'R', 'C', 'CSA' 등의 항목을 일일이 하드코딩하지 않아도 됩니다.

저는 한 시간 정도 작업을 해왔는데, 정규 표현식에 대한 모든 일치 항목을 검색하여 14를 16으로 바꾼 다음 원본 텍스트를 기존 값과 새 값으로 바꾸기를 실행했습니다.replace($myText,"TEST=CSA1400","TEST=CSA1600"), 특수 케이스를 잘 덮지도 못하고 마치 토끼굴 속으로 들어가는 것 같은 느낌입니다.

보존할 하위 식을 그룹화(예: 괄호 사이에 삽입)한 다음 변수를 통해 그룹을 참조해야 합니다.$1그리고.$2대체 문자열에 포함됩니다.다음과 같은 것을 시도해 보십시오.

$regexA = '( TEST=[A-Za-z]+)14(\d\d)$'

Get-ChildItem '*.txt' | ForEach-Object {
    $c = (Get-Content $_.FullName) -replace $regexA, '${1}16$2' -join "`r`n"
    [IO.File]::WriteAllText($_.FullName, $c)
}

스크립트 블록 위임자(Evaluator라고도 함)를 사용하는 예는 다음과 같습니다.

$regex = [regex]'( TEST=\D+)14(\d{2})\s*$'
$evaluator = { '{0}16{1}' -f $args[0].Groups[1..2] }
filter set-number { $regex.Replace($_, $evaluator) }

foreach ($file in Get-ChildItem  "*.txt")
 {
   ($file | get-content) | set-number | Set-Content $file.FullName
 }

대체 연산자보다 복잡하지만 대체 텍스트를 구성하기 위해 파워셸 연산자를 사용할 수 있으므로 스크립트 블록에 넣을 수 있는 모든 작업을 수행할 수 있습니다.

시도해 보기:

Get-ChildItem  "*.txt" |
Foreach-Object {
  $c = $_ | Get-Content | Foreach {$_ -replace '(?<=TEST=\D+)14(?=\d{2}(\D+|$))','16'}
  $c | Out-File $_.FullName -Enc Ascii
}

언급URL : https://stackoverflow.com/questions/19917106/use-powershell-to-replace-subsection-of-regex-result