1

I have a text file that looks like this:


      ;MPV_F4(isHold, taps, state)
      MPV_F5(isHold, taps, state)
         {
            if (taps == 1)
            {
                  if (isHold == 0)
                  {
                   ;[HV] T1 | cycle  mute | This is long LONG
                     Sendinput, {U+0398}  ;Θ ;   ;[rr] [cycle mute         ]
                  }
                  else
                  {
                    if (state)
                                          {
                                             while GetKeyState("f5", "p"){
                                                   Sendinput, {U+0399}  ;Ι ;   ;[rr] [add volume 10    ]  
                                                     sleep, 55
                                                 }  
                                          }
                          ; else
                          ;           {
                          ;           }
                  }
            }
         }      
      MPV_F6(isHold, taps, state)

      ;MPV_F7(isHold, taps, state)

      ;MPV_F8(isHold, taps, state)

      ;MPV_F9(isHold, taps, state)

      ;MPV_F11(isHold, taps, state)

      MPV_N2(isHold, taps, state)
         {
            if (taps == 1)
            {
                  if (isHold == 0)
                  {
                   ;[HV] T1 | cycle  mute | This is long LONG
                     Sendinput, {U+0398}  ;Θ ;   ;[rr] [cycle mute         ]
                  }
                  else
                  {
                    if (state)
                                          {
                                             while GetKeyState("f5", "p"){
                                                   Sendinput, {U+0399}  ;Ι ;   ;[rr] [add volume 10    ]  
                                                     sleep, 55
                                                 }  
                                          }
                          ; else
                          ;           {
                          ;           }
                  }
            }
         }
      ;MPV_N3(isHold, taps, state)
      ;MPV_N4(isHold, taps, state)
      ;MPV_N5(isHold, taps, state)

which essentially consists of a repeating pattern of:

FunctionName(isHold, taps, state)
{
 <Function Body>
}

I am trying to break it down into arrays that consists of the function name and body. I cant use the string MPV in my regex as there are other similar texts files whose function names does not contain MPV.
My exepected output is:

$MyVar [0] :

      MPV_F5(isHold, taps, state)
         {
            if (taps == 1)
            {
                  if (isHold == 0)
                  {
                   ;[HV] T1 | cycle  mute | This is long LONG
                     Sendinput, {U+0398}  ;Θ ;   ;[rr] [cycle mute         ]
                  }
                  else
                  {
                    if (state)
                                          {
                                             while GetKeyState("f5", "p"){
                                                   Sendinput, {U+0399}  ;Ι ;   ;[rr] [add volume 10    ]  
                                                     sleep, 55
                                                 }  
                                          }
                          ; else
                          ;           {
                          ;           }
                  }
            }
         } 

$MyVar [1] :

      MPV_N2(isHold, taps, state)
         {
            if (taps == 1)
            {
                  if (isHold == 0)
                  {
                   ;[HV] T1 | cycle  mute | This is long LONG
                     Sendinput, {U+0398}  ;Θ ;   ;[rr] [cycle mute         ]
                  }
                  else
                  {
                    if (state)
                                          {
                                             while GetKeyState("f5", "p"){
                                                   Sendinput, {U+0399}  ;Ι ;   ;[rr] [add volume 10    ]  
                                                     sleep, 55
                                                 }  
                                          }
                          ; else
                          ;           {
                          ;           }
                  }
            }
         }

At first I tried to use Get-Content's -Delimeter parameter:

$mytextfile = "c:\temp\mytextfile.txt"
Get-content $mytextfile -Delimiter '.*[^;]\(isHold, taps, state\)'

It keeps returning the entire content as a single object, After a few more variations I resorted to just using Get-Content -Raw and then -Split operator:

$MyVar = $mytextfile -Split (?m).*[^;]\(isHold, taps, state\)(?s).*\}

I continue to get unexpected results, most commonly the entire content being returned instead of arrays.

I am using RegEx101*, and options are closesly aligned to what powershell expects. I have tried many variations with no desired results.

Here is a link my RegEx101 page.

What could I be doing wrong here?

Any help would be truelly wellcome.

4
  • Can you please reformat your code into a readable format? Commented Nov 28, 2022 at 23:40
  • @Zak, I made some changes, not entirely sure if thats what you meant though Commented Nov 28, 2022 at 23:58
  • 1
    this regex might help you a bit. It's not a complete solution because it won't match the last function in the input, but otherwise it'll do. Commented Nov 29, 2022 at 0:05
  • @dc-ddfe this look really good. even as you say it being incomplete, it is a good example for me to build from. Thanks allot Commented Nov 29, 2022 at 0:54

1 Answer 1

1

Try the following:

$MyVar =
  [regex]::Matches(
    (Get-Content -Raw $mytextfile), 
    '(?sm)\w+\(isHold, taps, state\)\s*\{(?:.(?!\w+\(\w))+\}'
  ).Value

Note that this approach is computation-intensive and relies on detecting the end of a function not by properly detecting nested { / } pairs, but by assuming that the presence of any subsequent <funcname>(<wordcharacter> substring (e.g. 'MPV_F6(i') implies that the most recent } ended the function body.

See this regex101.com page.

Sign up to request clarification or add additional context in comments.

3 Comments

@mklement0 Fresh morning, fresh eyes! This works as expected and more. Strangely enough, I tried ommitting MPV from your RegEx and it still works as intended. This will serve as a good example to really go beyond a simple RegEx. Thanks allot!
@dc-ddfe, I misread your comment. I've updated the negative lookahead from (?:.(?!MPV_))+ to (?!\w+\(\w))+ to generalize it, which appears to work well enough for hellen_dorandt89, but, of course, it is no substitute for a language parsers that truly understands the file's syntax.
@hellen_dorandt89, glad to hear it. Please see the previous comment re generalizing the negative lookahead assertion. At least with your sample input, omitting it doesn't work for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.