Perhaps the following can help you get your desired final output, it is a more manual and classic approach, it doesn't intent to solve everything with regex but it does help with the logical conditions:
Get-Content file.txt | ForEach-Object {
# if the line starts with CODE= followed by a code
if ($_ -match '^CODE=(.+)') {
# capture the code (e.g. MMH4, PPH2, etc)
$code = $Matches[1]
# and go to next line
return
}
# if we have captured a code in previous lines
if ($code) {
# loop thru each match of a line containing a combination of `ABC=...&&DEF=...`
# we use [Regex]::Matches(..) here as there could be multiple `||` conditions
foreach ($match in [regex]::Matches($_, '(?:ABC=\d+&&DEF=\d+)+')) {
# replace `&&` with a TAB concatenated with TAB and the captured code
"$($match.Value.Replace('&&', "`t"))`t$code"
}
# then we clear this variable to look for a new line starting with CODE=
# NOTE: See the end of the answer to understand the usage of this
$code = $null
}
}
The above, using your sample text would produce the following output:
ABC=704 DEF=03 PPH2
ABC=706 DEF=04 PPH2
ABC=334 DEF=030 KK7
You might notice the use of $code = $null, this is a tiny optimization to not enter the if ($code) condition more than once for each appearance of a line starting with CODE=, it could be removed and removing it could have a different effect depending on the input, taking this as a small sample:
CODE=KK7
description=beg Area4 - ABC=334&&DEF=030
description=beg Area4 - ABC=335&&DEF=031
END
If left as-is, the result for the sample would be:
ABC=334 DEF=030 KK7
Whereas if that line of code is removed, the logic would match both inner lines:
ABC=334 DEF=030 KK7
ABC=335 DEF=031 KK7
EDIT
Looking at the latest edit on your question, you're seemingly wanting to convert your text into a TSV, for this I'd recommend to use a function where you can output the headers in its begin block; you could technically use ForEach-Object -Begin {...} too if you like.
So the code doesn't change that much from what was provided above, the regex pattern will use 2 capturing groups to get the value of ABC= and DEF=... see here for details: https://regex101.com/r/qvGBZy/1.
function ConvertTo-Tsv {
param(
[Parameter(ValueFromPipeline, Mandatory)]
[string] $Line,
# using a parameter instead of hardcoding them in `begin {..}`
# gives more flexibility, you can provide new headers when needed
[Parameter(Position = 0)]
[string[]] $Header = ('ABC', 'DEF', 'CODE')
)
begin {
# output the header joined by TAB
$Header -join "`t"
$re = [regex]::new('(?:ABC=(?<abc>\d+)&&DEF=(?<def>\d+))+')
}
process {
if ($Line -match '^CODE=(.+)') {
$code = $Matches[1]
return
}
if ($code) {
foreach ($match in $re.Matches($Line)) {
# output values of ABC= and DEF= with the value of CODE=
"$($match.Groups['abc'])`t$($match.Groups['def'])`t$code"
}
$code = $null
}
}
}
Then the usage is pretty straight forward, read the file content, pipe to our function and lastly pipe to file storage:
Get-Content myFile.txt | ConvertTo-Tsv | Set-Content myOutput.tsv
The expected output using the function given the sample input text would be:
ABC DEF CODE
704 03 PPH2
706 04 PPH2
334 030 KK7
And we can tell this is a valid TSV given that a conversion from it produces the following objects:
PS> Get-Content sample.txt | ConvertTo-Tsv | ConvertFrom-Csv -Delimiter "`t"
ABC DEF CODE
--- --- ----
704 03 PPH2
706 04 PPH2
334 030 KK7
ABC=...always come with&&thenDEF=...?ABC=...&&DEF=...||ABC=...&&DEF=...or could there be more "OR" conditions?