Jump to content

Help spilitting string.


bourny
 Share

Recommended Posts

Hi,

 

I am trying to split a string that has multiple spaces but I need to split by the spaces.  The issue I have is there is parts in the quotes that also have spaces.   example is below.  

My ultimate goal is to split the line and return the following array

0 - CPU="AMD 64"
1 - OSType="64 bit"
2 - OS="Windows server 2012 R2"
3 - Bootfirmware= "Bios"

The attempt 2 below gets very close to this but I am having to blag it by splitting the string with singlequote+space which is a crude way and could voilate any parts of a longer string that does not conform to this rule.

#include <String.au3>
#include <Array.au3>

;Attempt 1
;This gives me the parts inside the quotes but I have no way to see the tags that they belong to
$String = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"'

   Local $aArray = _StringBetween($String, '="', '"')
   _ArrayDisplay($aArray)

   $start = 1
   For $element in $aArray

      $pos = StringInStr($String, $element)

   Next



;Attempt 2 - Split by space however this does work to an extent only because I am using the qotes and space however this could be violated by something in a much longer string that does not conform.

$aArrayOfEntries = StringSplit($String, '" ',  $STR_ENTIRESPLIT )
_ArrayDisplay($aArrayOfEntries)

 

Any help appreciated.

 

Link to comment
Share on other sites

Funny Problem :) 

First idea was "why isn't he splitting at the = marks?". Well, doh! Does not work...

So one way to do it is using RegEx:

#include <Array.au3>
$String = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"'

$aArrayOfEntries = StringRegExp($String, '(?isU)(.*)=("[^"]*")', 3)
_ArrayDisplay($aArrayOfEntries)

Global $aFinal[4][2]
$line = 0
    for $i= 0 to UBound($aArrayOfEntries)-2 Step 2
        $aFinal[$line][0] = $aArrayOfEntries[$i]
        $aFinal[$line][1] = $aArrayOfEntries[$i+1]
        $line +=1
    Next
_ArrayDisplay($aFinal)

best regards

Marc

Any of my own codes posted on the forum are free for use by others without any restriction of any kind. (WTFPL)

Link to comment
Share on other sites

@bourny
You could use StringRegExpReplace() at your advantage as well :)

Global $strTestString = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"', _
       $strPattern = '(\w+)(?:=")([^"]+)(?:")(?:\s?)', _
       $arrResult[1][2]


_ArrayAdd($arrResult, StringRegExpReplace($strTestString, $strPattern, '\1|\2' & @CRLF))
If @error Then
    ConsoleWrite("Error while adding the array in the $arrResult. Error: " & @error & @CRLF)
    Exit
Else
    _ArrayDelete($arrResult, 0)                      ; Deleting the first blank element
    _ArrayDelete($arrResult, UBound($arrResult) - 1) ; Deleting the last blank element
    _ArrayDisplay($arrResult)
EndIf

By the way, nice SRE @Marc ^_^

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

@Marc - Perfect.  Exactly what I need.  I will see if I can understand what you did here with the string pattern as clearly I do not understand that bit and how its used.

@FrancescoDiMuro - This is also the exact solution I need and I will need to also understand the sting pattern used here as I do not understand it.  Also thanks for the compliment on the SRE.

$strPattern = '(\w+)(?:=")([^"]+)(?:")(?:\s?)'
Link to comment
Share on other sites

@bourny

Glad it helped.- In general, this Regex does the following:

(?isU)    ; setting the options for thr regex enine - Ignore case, interpret the string as one line and always use the shortest possible match when searching
(.*)      ; search for literally everything... and keep the matching text in the array
=         ; which is followed by an =
("[^"]*") ; which is followed by an ", followed by anything which is NOT a ", which is followed by an " - and keep the matching text in the array

@FrancescoDiMuro

Clever idea, I like it. :) Especially avoiding my clumsy reformatting of the array.

Any of my own codes posted on the forum are free for use by others without any restriction of any kind. (WTFPL)

Link to comment
Share on other sites

@Marc and @FrancescoDiMuro - Thanks for the explanation and link to the guide on this.  I will spend some time understanding this so I can use this going forward for tricky strings like this.  I can usually deal with any stings but seemingly this one defeated me.

i have applied this to my core script and its working perfectly.  

Appreciate the time you spent on this.

Link to comment
Share on other sites

A funny non-regex workaround  :)

#include <Array.au3>

Global $strTestString = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"'

$tmp = @tempdir & "\test.ini"
FileWrite($tmp, "[test]" & @crlf & StringReplace(StringReplace($strTestString, '" ', '"' & @crlf), '"', "") )
$res = IniReadSection($tmp, "test")
FileDelete($tmp)
_ArrayDisplay($res)

 

Link to comment
Share on other sites

#include<array.au3>

$String = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"'

$arr = stringsplit(StringReplace($String , '" ' , '"' & @LF) , @LF , 2)

_ArrayDisplay($arr)

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

and another workaround without regex:

#include <String.au3>
#include <Array.au3>

$String = 'CPU="AMD 64" OSType="64 bit" OS="Windows server 2012 R2" bootfirmware="Bios"'

Local $aArray = _StringBetween(' "' & $String, '"', '"')
For $i = UBound($aArray) - 2 To 0 Step -2
    $aArray[$i] = $aArray[$i] & $aArray[$i + 1]
    _ArrayDelete($aArray, $i + 1)
Next
_ArrayDisplay($aArray)

 

Link to comment
Share on other sites

As always I am impressed with the response from the forum.  

 

@mikell - Very nice use of the file output to extract the information I need.  Never considered this approach.

@iamtheky - You have done this in less lines of code and I will be interested why the " " empty space has not worked but instead the @LF has worked but clearly a difference.  I am impressed with your simple solution .

@autoBurt - Very simple idea by combining the array elements to produce the same result.  

 

Thankyou all for your contributions and showing the various ways of tacking this problem

 

Link to comment
Share on other sites

caveat: i dont know if this explanation helps, or makes it worse :mellow:

you only want to split on spaces preceded by double quotes, however spaces exist elsewhere.

Replacing those spaces with a character that does not exist elsewhere in the string solves the problem by having a unique character to split on.

*You could also stringsplit on more than one character '" ' and require the full match, but then you have to put stuff back at the end.

 

Edited by iamtheky
grammar/structure/i talk weird

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Spoiler

 

Do you have potential edge cases you need to accomodate? If there is ever a chance a line feed could creep into your input, then my solution would not be recommended.

Barring that I would race 'em, fileops -vs- regex is a rare contest. 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...