Multiline array

This topic contains 3 replies, has 4 voices, and was last updated by  Curtis Smith 3 months ago.

  • Author
    Posts
  • #79018

    Aaron
    Participant

    Hello,

    I have an array that is housing multiline values as seen below.

    I want to be able to go through the array and identify the menu options, these are designated by the numbers, "1 Enter/update accounts for recon" etc...

    $array[0]
    
    MENUNAMEABC Account Recon
      1 Enter/update accounts for recon
      2 Enter/update issued checks
      3 Enter/update paid checks
      5 Add paid checks from file
     10 Add issued AP checks from 
     11 Add deposit trans from 
     13 Post reconciled transactions
     14 Purge paid checks in acct recon
     20 Paid check exception listing
     21 Paid check transaction listing
     22 Outstanding checks register
     24 Statement for acct recon by ck #
     25 Acct recon statement by status
     26 Account recon account listing
      User       Name                                     Allowed Options
      FEDCAB     User - Derp Derpman                      1,2,3,5,10,11,13,14,20,21,22,24,25,26
      ABCDEF     User- Fake Name                          1,2,3,5,10,11,13,14,20,21,22,24,25,26
      ABCXYZ     User - Tom Brooks                        1,2,3,5,10,11,13,14,20,21,22,24,25,26
    

    Is there a way to go line by line in an array item?

    foreach($line in $array[0])
    {
       #regex or something to find each menu
    }
    

    Any help would be greatly appreciated!

  • #79049

    Olaf Soyk
    Participant

    The normal way to enumerate the elements of an array is to use a loop. Either a forach loop or with the pipeline and foreach-object. If the element of the array is another array you can enumerate this with a loop. Either a foreach loop or with the pipeline and foreach-object. If not all elements of the array are arrays you want to enumerate you would have to check the type before with some conditional statements.

  • #79064

    Kevyn
    Participant

    I'm pretty knew at RegEx, so maybe Olaf can check me here, but this worked for me. I based in the assumption that the format you gave us for the data does not change. Also, I had the content what you're showing in $array[0] in a file called Source.txt. The additional thing I did was trim the spaces off the beginning and ends of the menu lines.

    $Data = Get-Content C:\data\Source.txt
    ForEach($Line in $Data)
    {
      If($Line -match "(\s)*(\d)+\s[\w\W]+")
      {
        Write-Output "This is a menu item: $($Line.Trim())"
      }
    }
    
    This is a menu item: 1 Enter/update accounts for recon
    This is a menu item: 2 Enter/update issued checks
    This is a menu item: 3 Enter/update paid checks
    This is a menu item: 5 Add paid checks from file
    This is a menu item: 10 Add issued AP checks from
    This is a menu item: 11 Add deposit trans from
    This is a menu item: 13 Post reconciled transactions
    This is a menu item: 14 Purge paid checks in acct recon
    This is a menu item: 20 Paid check exception listing
    This is a menu item: 21 Paid check transaction listing
    This is a menu item: 22 Outstanding checks register
    This is a menu item: 24 Statement for acct recon by ck #
    This is a menu item: 25 Acct recon statement by status
    This is a menu item: 26 Account recon account listing
    

    So, the RegEx is broken down like this:

    1. (\s)* – Zero, or more, whitespace characters, including a tab, space, or carriage return...followed by...
    2. (\d)+ – One, or more digits(0 – 9)...followed by...
    3. \s – One whitespace character...followed by...
    4. [\w\W]+ – Any combination of at least one word character (letters, numbers, & underscores) or non-word character (whitespace & punctuation)

    If the format of your text is very rigid (Ex: There is always just two blank spaces at the beginning of the lines that match the menu items, then you can start your RegEx with: (\s){2}). You can do a similar thing for your menu numbers. If it's only going to be one, or two, digits, then you can do: (\d){1,2}. Etc... So, you could have:

    If($Line -match "(\s){2}(\d){1,2}\s[\w\W]+")
    

    Don Jones has a great book called Learn Windows PowerShell In A Month Of Lunches. In Chapter 24, he goes over how to use RegEx to parse text files. RegEx can be super complex, but that chapter gave me a good start.

    Hope that helps.

  • #79187

    Curtis Smith
    Participant

    You would have to know what your delimiter is within the array element and split by that delimiter.

    For example:

    $array = @()
    $array += @'
    MENUNAMEABC Account Recon
      1 Enter/update accounts for recon
      2 Enter/update issued checks
      3 Enter/update paid checks
      5 Add paid checks from file
     10 Add issued AP checks from 
     11 Add deposit trans from 
     13 Post reconciled transactions
     14 Purge paid checks in acct recon
     20 Paid check exception listing
     21 Paid check transaction listing
     22 Outstanding checks register
     24 Statement for acct recon by ck #
     25 Acct recon statement by status
     26 Account recon account listing
      User       Name                                     Allowed Options
      FEDCAB     User - Derp Derpman                      1,2,3,5,10,11,13,14,20,21,22,24,25,26
      ABCDEF     User- Fake Name                          1,2,3,5,10,11,13,14,20,21,22,24,25,26
      ABCXYZ     User - Tom Brooks                        1,2,3,5,10,11,13,14,20,21,22,24,25,26
    '@
    
    $array[0].Count
    ($array[0] -split "`r`n").Count
    
    $array[0] -split "`r`n" | Select-String -Pattern "^ +\d+"

    In the above, I create a blank array, and then add a single array element with the full menu you posted in the original question. I then show that element 0 in the array is seen as a single string. Since I know that the lines are wrapped using the carriage return and new line characters, I use those characters as the delimiter for the -split operator. Afterward I show that this results in 19 individual strings. Using Select-String and a RegEx pattern, I filter the strings to only show those that begin with one or more spaces followed by one or more numbers.

    Results:

    1
    19
    
      1 Enter/update accounts for recon
      2 Enter/update issued checks
      3 Enter/update paid checks
      5 Add paid checks from file
     10 Add issued AP checks from 
     11 Add deposit trans from 
     13 Post reconciled transactions
     14 Purge paid checks in acct recon
     20 Paid check exception listing
     21 Paid check transaction listing
     22 Outstanding checks register
     24 Statement for acct recon by ck #
     25 Acct recon statement by status
     26 Account recon account listing

You must be logged in to reply to this topic.