Multiline array

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!

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.

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.

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