I have a string like this that I get from a database:
[email protected]&name=John
I'd like to know if there is an easy way to extract the data and put them into two variables, user and name.
I have a string like this that I get from a database:
[email protected]&name=John
I'd like to know if there is an easy way to extract the data and put them into two variables, user and name.
@Marc, As per @Dan Bracuk suggestion you can split your string by using mentioned delimeter first as & and again as =. Please refer my below code that will help you. I hope.
<cfset yourInput= '[email protected]&name=John'>
<!--- Get the first value. I mean "user" part --->
<cfset splitFirstPart = listfirst(yourInput,'&', true)>
<cfset splitLastPart = listlast(yourInput, '&', true)>
<!--- Get the second part value --->
<!--- Above values are split by using & --->
<cfset user = listlast(splitFirstPart, '=', true)>
<Cfset name = listlast(splitLastPart, '=', true)>
<!---
Now we can again split the list by using =.
Now you can see the result.
--->
<cfoutput>
User : #user# <br/>
Name : #name#
</cfoutput>
If you need any other CFML functions & clarification please refer https://cfdocs.org/
Thanks.
Here is my take on how to solve this one.
I like having a structure as final result. I also like working with the each functions as an implicit loop.
<cfscript>
yourInput= '[email protected]&name=John';
variables.result = {};
ListEach(yourInput,
function(item) { variables.result[listfirst(item, "=")] = listLast(item, "="); },
"&");
writedump(result);
</cfscript>
To add to this answer for future readers, there are a couple of ways to make this more dynamic.
Essentially, you are just parsing a delimited list twice and pulling out the pieces you need. ColdFusion allows several ways to do that.
For illustration, I've added to the original string.
string="[email protected]&name=John&somethingelse=42&foo&base64Msg=QmVFeGNlbGxlbnRUb0VhY2hPdGhlcg==" ;
My preferred way to parse this is to us a CF function that returns a struct of all of the pieces I need.
public Struct function parseURLParamString( required String inURLStr ) {
/// Initialize the return struct.
var retStruct = {} ;
// Use listEach() function to iterate over the list with delim "&"
arguments.inURLStr.listeach(
function(item){
// listFirst gets 1st list element. listRest() gets all but 1st element. Delim "="
retStruct[listFirst(item,"=")] = listRest(item,"=") ;
}
, "&"
) ;
return retStruct ;
}
writeDump( parseURLParamString(string) ) ;
This will return:
Then you can just reference the variables you need from your returned struct.
But if you need to create actual variables instead of pulling them from a struct, you can do so like this:
arguments.inURLStr.listeach(
function(item){
variables[listFirst(item,'=')] = listRest(item,"=") ;
}
, "&"
) ;
... and then change your outer function to either return Void or nothing and drop the struct from it. You can reference the variables like user = #user#. This would require you to know the variables in advance, whereas when passing a specific struct, you can just loop over the struct and output the keys/values. Technically you can also loop over the variables scope, but there will likely be a lot of other variables in there, too.
If you want, you can also use getToken(), but it has the same limitation that listLast() does. If your value contains the second delimiter text (like a padded Base64 string), then those characters would be treated as a delimiter and be left off of your value. For base64Msg = QmVFeGNlbGxlbnRUb0VhY2hPdGhlcg==, getToken()/listLast() will return QmVFeGNlbGxlbnRUb0VhY2hPdGhlcg, where listRest() will give you QmVFeGNlbGxlbnRUb0VhY2hPdGhlcg==. Or even worse, if the character is in the middle of the string, it will be truncated. ListLast() removes the first item of a delimited list and returns the rest of the list, so if your string contains the delimiter, it will return the full value.
Lastly, since this appears to be a string from a URL, you probably want to sanitize and encode the string before you store it in the database.
If you save the encoded value, it will likely turn your delimiters into their encoded values. The above frunctions only support single-character delimiters, so wouldn't be usable as above (unless decoding before sending to the splitting function). listToArray allows multi-character delimiters. So that may be one way to split them.
In the end, there are a lot of characters that are allowed a URL string, # and = being two that are sure to cause you issues without encoding and proper handling.
You could use "ListToArray" using "&" as delimiter to split each value, and then use again (or use ListFirst and ListLast if there is only 2 values) but this time using "=" as delimiter, that way you will have ["[email protected]", "name=John"] as First result, and [[[user],[[email protected]]],[[name],[John]]] as second.
I usualy recomend use structs instead of simple variables, here goes one example
<cfscript>
/* My Raw string */
MyString = "[email protected]&name=John";
/* Breaking my single string in multiple values */
MyArrayOfValues = ListToArray(MyString, "&");
/* Creating my struct o hold my values */
MyStruct = StructNew();
/* Interating over my values */
for (Value in MyArrayOfValues){
// First Interaction will be: [email protected] and the second will be name=John and etc...
/* Get My attribute name */
MyAttributeName = ListFirst(Value, "=");
/* Get My attribute value */
MyAttributeValue = ListLast(Value, "=");
/* Evaluate the values of you borth variables and asign each other */
Evaluate("MyStruct.#LCase(MyAttributeName)# = '#MyAttributeValue#'");
}
/* Here you can see your value printed as struct formed by 2 atributes, name and user, both in lower case */
writeDump(MyStruct);
/* Here one example how to use this data */
writeOutput("
Hi my name is #MyStruct.name# and my user is #MyStruct.user#!
");
</cfscript>
This way is more generic approach, since you probabily will have more columns in your database or even can use it with other data from another data base, always following the same struct... values seperated by & and attribute and value by =
SpanExcludingpaired with other string functions. helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/… - TRose&character and the inner one by the=character. - Dan Bracuk