bourny Posted December 4, 2018 Share Posted December 4, 2018 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 More sharing options...
Marc Posted December 4, 2018 Share Posted December 4, 2018 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 FrancescoDiMuro 1 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 More sharing options...
FrancescoDiMuro Posted December 4, 2018 Share Posted December 4, 2018 @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 Marc 1 Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
bourny Posted December 4, 2018 Author Share Posted December 4, 2018 @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 More sharing options...
FrancescoDiMuro Posted December 4, 2018 Share Posted December 4, 2018 @bourny As someone was suggesting here on the Forum a couple of days ago, you can use regex101 to have a full explanation (plus an online regex editor) of what is going on with that pattern, and your test string Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Marc Posted December 4, 2018 Share Posted December 4, 2018 @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. FrancescoDiMuro 1 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 More sharing options...
bourny Posted December 4, 2018 Author Share Posted December 4, 2018 @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 More sharing options...
FrancescoDiMuro Posted December 4, 2018 Share Posted December 4, 2018 @bourny Happy to have helped Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
mikell Posted December 4, 2018 Share Posted December 4, 2018 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 More sharing options...
iamtheky Posted December 4, 2018 Share Posted December 4, 2018 #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 More sharing options...
AutoBert Posted December 4, 2018 Share Posted December 4, 2018 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 More sharing options...
bourny Posted December 4, 2018 Author Share Posted December 4, 2018 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 More sharing options...
iamtheky Posted December 4, 2018 Share Posted December 4, 2018 (edited) caveat: i dont know if this explanation helps, or makes it worse 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 December 4, 2018 by iamtheky grammar/structure/i talk weird FrancescoDiMuro 1 ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted December 4, 2018 Share Posted December 4, 2018 @iamtheky That edit Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
bourny Posted December 4, 2018 Author Share Posted December 4, 2018 @iamtheky - Works in my live program so looking good. Splits exactly as it should and overcomes the issue I initially faced. I am spoilt for choice on which solution to use. Link to comment Share on other sites More sharing options...
iamtheky Posted December 4, 2018 Share Posted December 4, 2018 (edited) 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 December 4, 2018 by iamtheky ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now