how to remove string from URL? [duplicate] - regex

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to strip out a url variable
I have url http://localhost/abc/detail.cfm?iId=1711471&countrysearch=3693&itemnumbersearch=&keywordsearch=&purl=%2FIGPCI%2Fthumbs%2Ecfm%3Fcountrysearch%3D3693%26itemnumbersearch%3D%26keywordsearch%3D%26x%3D78%26y%3D10&productid=1111&recordindex=1.
I want to search product details on clicking link called "next" each time i need to prepare new URL with new value of productid and recordindex.for example i have four product with respect to countryid="3693",
productid productname
1 p1
2 p2
3 p3
4 p4
when next click new URL prepare with productid=1 and recordindex=1,again click then URL is productid=2 and record id =2 and so on.
for getting URL i have used following code:
<cfset currentURL = "#CGI.SERVER_NAME#" & "#CGI.PATH_INFO#" & "#CGI.query_string#">
which give me the current url
then i prepare new url with below code:
<cfif queryString.recordset gt 0> <cfset recordindex=#recordindex#+1> <cfset newUrl=currentURL & '&productid=#queryString.poductid[recordindex]#&recordindex=#recordindex#' </cfif>
with this code that each time it's append url value with old with new one.
like:
http://localhost/abc/detail.cfm?iId=1711471&countrysearch=3693&itemnumbersearch=&keywordsearch=&purl=%2FIGPCI%2Fthumbs%2Ecfm%3Fcountrysearch%3D3693%26itemnumbersearch%3D%26keywordsearch%3D%26x%3D78%26y%3D10&productid=1111&recordindex=1&productid=2&recordindex=2
my question how to remove old &productid=1111&recordindex=1 in old URL.i tried with replace function but it replace when string are match,in my case every time product and recordindex values are change.how to remove old string using regular expression.please help me.
Thanks

You don't need regex for this. In fact, someone has already built a UDF for this.
QueryStringDeleteVar
Example:
<cfset currentURL = CGI.SERVER_NAME & CGI.PATH_INFO & queryStringDeleteVar("productid,recordindex")>
UDF code:
<cfscript>
/**
* Deletes a var from a query string.
* Idea for multiple args from Michael Stephenson (michael.stephenson#adtran.com)
*
* #param variable A variable, or a list of variables, to delete from the query string.
* #param qs Query string to modify. Defaults to CGI.QUERY_STRING.
* #return Returns a string.
* #author Nathan Dintenfass (michael.stephenson#adtran.comnathan#changemedia.com)
* #version 1.1, February 24, 2002
*/
function queryStringDeleteVar(variable){
//var to hold the final string
var string = "";
//vars for use in the loop, so we don't have to evaluate lists and arrays more than once
var ii = 1;
var thisVar = "";
var thisIndex = "";
var array = "";
//if there is a second argument, use that as the query string, otherwise default to cgi.query_string
var qs = cgi.query_string;
if(arrayLen(arguments) GT 1)
qs = arguments[2];
//put the query string into an array for easier looping
array = listToArray(qs,"&");
//now, loop over the array and rebuild the string
for(ii = 1; ii lte arrayLen(array); ii = ii + 1){
thisIndex = array[ii];
thisVar = listFirst(thisIndex,"=");
//if this is the var, edit it to the value, otherwise, just append
if(not listFind(variable,thisVar))
string = listAppend(string,thisIndex,"&");
}
//return the string
return string;
}
</cfscript>
Although, since you're looking to replace URL parameter values, QueryStringChangeVar would probably be more of what you want.
<cfscript>
/**
* Changes a var in a query string.
*
* #param name The name of the name/value pair you want to modify. (Required)
* #param value The new value for the name/value pair you want to modify. (Required)
* #param qs Query string to modify. Defaults to CGI.QUERY_STRING. (Optional)
* #return Returns a string.
* #author Nathan Dintenfass (nathan#changemedia.com)
* #version 2, September 5, 2002
*/
function QueryStringChangeVar(variable,value){
//var to hold the final string
var string = "";
//vars for use in the loop, so we don't have to evaluate lists and arrays more than once
var ii = 1;
var thisVar = "";
var thisIndex = "";
var array = "";
var changedIt = 0;
//if there is a third argument, use that as the query string, otherwise default to cgi.query_string
var qs = cgi.query_string;
if(arrayLen(arguments) GT 2)
qs = arguments[3];
//put the query string into an array for easier looping
array = listToArray(qs,"&");
//now, loop over the array and rebuild the string
for(ii = 1; ii lte arrayLen(array); ii = ii + 1){
thisIndex = array[ii];
thisVar = listFirst(thisIndex,"=");
//if this is the var, edit it to the value, otherwise, just append
if(thisVar is variable){
string = listAppend(string,thisVar & "=" & value,"&");
changedIt = 1;
}
else{
string = listAppend(string,thisIndex,"&");
}
}
//if it was not changed, add it!
if(NOT changedIt)
string = listAppend(string,variable & "=" & value,"&");
//return the string
return string;
}
</cfscript>

Related

Extract the digits and append it in a different cell?

I am trying to automatically RegExp(extract) the digits(AREA number) in Column 3 combined with the Text 'A' to append in Column 1 Date INDEX.
The problem is I'm not yet familiar in using google sheets app-scripts.
Tried looking for solutions with similar situation as me, but to no avail.
I don't know to put VBA to app-scripts.
Tried using some codes.
I still can't seem to make it work.
Can anyone point me in the right direction?
Thank you if you can help me out. Thanks.
EDIT:
The scenarios is in the office i cant make column for the formula.
It must be "behind the scene".
My googlesheets
//NOT WORKING code
function onEdit(e) {
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var regExp = new RegExp("\d*"); // Extract the digits
var dataIndex = regExp.exec(area)[1];
if(rg.columnStart==3) { // Observe column 3
var vA=rg.getValues();
for(var i=0;i<vA.length;i++){
if(vA[i][0]) {
sh.getRange(rg.rowStart + i,1).appendText((dataIndex) +'A'); // append to column 1 with 'A' and extracted digits
}
}
}
}
This answer extends your approach of using a script with an OnEdit trigger. But there are a number of differences between the two sets of code.
The most significant difference is that I have used the Javascript split method (var fields = value.split(' ');) to get distinct values from the data entry.
Most of the other differences are error checking:
if(rg.columnStart === 3 && area === "work") {: test for sheet="work" as well as an edit on Column C
var value = e.value.toUpperCase();: anticipate that the test might be in lower case.
if (fields.length !=2){: test that there are two elements in the data entry.
if (fields[0] != "AREA"){: test that the first elment of the entry is the word 'area'
if (num !=0 && numtype ==="number"){; test that the second element is a number, and that it is NOT zero.
if (colA.length !=0){: test that Column A is not empty
var newColA = colA+"A"+num;: construct the new value for Column A by using unary operator '+'.
function onEdit(e){
// so5911459101
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
//Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value.toUpperCase();
//Logger.log("DEBUG: the value = "+value+", length = "+value.length+", uppercase = "+value.toUpperCase());
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// Logger.log("DEBUG: number of fields = "+fields.length)
// test if there are two fields in the value
if (fields.length !=2){
// Logger.log("DEBUG: the value doesn't have two fields")
}
else{
// Logger.log("DEBUG: the value has two fields")
// test if the first field = 'AREA'
if (fields[0] != "AREA"){
// Logger.log("DEBUG: do nothing because the value doesn't include area")
}
else{
// Logger.log("DEBUG: do something because the value does include area")
// get the second field - it should be a value
var num = fields[1];
num =+num
var numtype = typeof num;
// Logger.log("DEBUG: num= "+num+" type = "+numtype); //number
// test type of second field
if (num !=0 && numtype ==="number"){
// Logger.log("DEBUG: the second field IS a number")
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// test if Column A is empty
if (colA.length !=0){
var newColA = colA+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
// Logger.log("DEBUG: do nothing because column A is empty")
}
}
else{
// Logger.log("DEBUG: the second field isn't a number")
}
}
}
}
else{
//Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}
REVISION
If the value in Column C is sourced from data validation, then no need for and testing except that the edit was in Column C and the sheet = "work".
Included two additional lines of code:
var colAfields = colA.split('-');
var colAdate = colAfields[0];
This has the effect of excluding any existing characters after the hyphen, and re-establishing the hyphen, row number plus "A" and the AREA numeral.
function onEdit(e){
// so5911459101 revised
// only one test - check for ColumnC and sheet="work"
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value
//Logger.log("DEBUG: the value = "+value+", length = "+value.length);
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// get the second field - it should be a value
var num = fields[1];
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// use Javascript split on Column A in case of existing value
var colAfields = colA.split('-');
var colAdate = colAfields[0];
// build new value
var newColA = colAdate+"-"+row+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}

Google Sheets Search and Sum in two lists

I have a Google Sheets question I was hoping someone could help with.
I have a list of about 200 keywords which looks like the ones below:
**List 1**
Italy City trip
Italy Roundtrip
Italy Holiday
Hungary City trip
Czechia City trip
Croatia Montenegro Roundtrip
....
....
And I then have another list with jumbled keywords with around 1 million rows. The keywords in this list don't exactly match with the first list. What I need to do is search for the keywords in list 1 (above) in list 2 (below) and sum all corresponding cost values. As you can see in the list below the keywords from list 1 are in the second list but with other keywords around them. For example, I need a formula that will search for "Italy City trip" from list 1, in list 2 and sum the cost when that keyword occurs. In this case, it would be 6 total. Adding the cost of "Italy City trip April" and "Italy City trip June" together.
**List 2** Cost
Italy City trip April 1
Italy City trip June 5
Next week Italy Roundtrip 4
Italy Holiday next week 1
Hungary City holiday trip 9
....
....
I hope that makes sense.
Any help would be greatly appreciated
try:
=ARRAYFORMULA(QUERY({IFNA(REGEXEXTRACT(PROPER(C1:C),
TEXTJOIN("|", 1, SORT(PROPER(A1:A), 1, 0)))), D1:D},
"select Col1,sum(Col2)
where Col1 is not null
group by Col1
label sum(Col2)''", 0))
You want to establish whether keywords in one list (List#1) can be found in another list (List#2).
List#2 is 1,000,000 rows long, so I would recommend segmenting the list so that execution times are not exceeded. That's something you will be able to establish by trial and error.
The solution is to use the javascript method indexOf.
Paraphrasing from w3schools: indexOf() returns the position of the first occurrence of a specified value in a string. If the value is not found, it returns -1. So testing if (idx !=-1){ will only return List#1 values that were found in List#2. Note: The indexOf() method is case sensitive.
function so5864274503() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var srcname = "source";
var tgtname = "target";
var sourceSheet = ss.getSheetByName(srcname);
var targetSheet = ss.getSheetByName(tgtname);
// get the source list
var sourceLR = sourceSheet.getLastRow();
var srcData = sourceSheet.getRange(1,1,sourceLR).getValues();
//get the target list
var targetLR = targetSheet.getLastRow();
var tgtlist = targetSheet.getRange(1,1,targetLR,2).getValues();
var totalcostvalues = [];
// start looping through the keywords (list 1)
for (var s = 0;s<srcData.length;s++){
var totalcost = 0;
var value = srcData[s][0]
// start looping through the strings (List 2)
for (var i=0;i<tgtlist.length;i++){
// set cost to zero
var cumcost = 0;
// use indexOf to test if keyword is in the string
var idx = tgtlist[i][0].indexOf(value);
// value of -1 = no match, value >-1 indicates posuton in the string where the key word was found
if (idx !=-1){
var cost = tgtlist[i][1]
cumcost = cumcost + cost;
totalcost = totalcost+cost
}
}//end of loop - list2
//Logger.log("DEBUG: Summary: "+value+", totalcost = "+totalcost)
totalcostvalues.push([totalcost])
}// end of loop - list1
//Logger.log(totalcostvalues); //DEBUG
sourceSheet.getRange(1,2,sourceLR).setValues(totalcostvalues);
}
I also got this one, but it's case sensitive a bit
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var valuesSheet1 = sheet1.getRange(2,1, (sheet1.getLastRow()-1), sheet1.getLastColumn()).getValues();
var valuesCol1Sheet1 = valuesSheet1.map(function(r){return r[0]});
var valuesCol2Sheet1 = valuesSheet1.map(function(r){return r[1]});
Logger.log(valuesCol2Sheet1);
var valuesSheet2 = sheet2.getRange(2,1, (sheet2.getLastRow()-1)).getValues();
var valuesCol1Sheet2 = valuesSheet2.map(function(r){return r[0]});
for (var i = 0; i<= valuesCol1Sheet2.length-1; i++){
var price = 0;
valuesCol1Sheet1.forEach(function(elt,index){
var position = elt.toLowerCase().indexOf(valuesCol1Sheet2[i].toLowerCase());
if(position >-1){
price = price + valuesCol2Sheet1[index];
}
});
sheet2.getRange((i+2),2).setValue(price);
};
}

For loop to access dictionary

I have a NSDictionary of type String:AnyObject, and I want to have it be type String:String. How can I convert them with the same key to type string using a loop? I would think I could figure it out, but Xcode 6 sourcekit keeps crashing whenever I put in a for loop for the dictionary.
PS. I'm writing this in Swift, not Obj-C.
This way you can loop over the dictionary for objects:AnyObject:
let dict = ["A":1, "B":2, "C":3]
var string = ""
for object in dict.values {
string += "\(object)"
}
// string = "312"
If you want to loop over just the keys change to .keys as in the following:
for key in dict.keys {
string += key
}
// string = "CAB"
Finally to loop over both keys and values with a Tuple (key, object) :
let dict = ["A":1, "B":2, "C":3]
var string = ""
var sum = 0
for (key, object) in dict {
string += key
sum += object
}
// sum = 6
// string = "CAB"
Note: This works with Beta 3.

Add a dynamic key to an anonymous List

How can I add a dynamic key to an anonymous List such as the mydatetime below:
DateTime myDateTime = DateTime.Parse(datepickerval, ukCulture.DateTimeFormat);
var qid = (from p in db.Vw_INTERACTPEOPLE
select p
);
var AvilList = new List<object>();
var ddate = myDateTime.DayOfWeek.ToString().Substring(0, 3) + "Jul" + myDateTime.Day;
foreach (var q in qid)
{
AvilList.Add(
new
{// Availability
Name = q.Fullname,
here >>> ddate = "Some Test"
});
As adam says above there is no way to do this using Lists, however since the Slickgrid is expecting a Json return, I simply built the string in .net then returned it via the JavaScriptSerializer serializer, then in the code behind simply used eval to de-serialize back into an array.

Coldfusion Query Object Manipulation

I have a coldfusion recordset like the following:
id name
1 dog
1 dog
2 cat
2 cat
5 lion
The recordcount is 5 but I want without changing my SQL to retrieve the total unique id (in that case 3) using coldfusion.
If I understand your question correctly you want to count unique ids? Use a Query of Query:
<cfquery datasource="quackit" name="GetAll">
select * from myTable
</cfquery>
<cfquery dbtype="query" name="GetUnique">
select distinct(id) from GetAll
</cfquery>
#GetUnique.recordCount#
An alternative method would be to get the IDs into a list, de-dupe it, and then count the result.
<cfset idList = valueList(myquery.id) />
<cfset dedupedIDlist = ListDeleteDuplicates(idList) />
<cfset uniqueIDcount = listLen(dedupedIDlist) />
ListDeleteDuplicates():
<cfscript>
/**
* Case-sensitive function for removing duplicate entries in a list.
* Based on dedupe by Raymond Camden
*
* #param list The list to be modified. (Required)
* #return Returns a list.
* #author Jeff Howden (cflib#jeffhowden.com)
* #version 1, July 2, 2008
*/
function ListDeleteDuplicates(list) {
var i = 1;
var delimiter = ',';
var returnValue = '';
if(ArrayLen(arguments) GTE 2)
delimiter = arguments[2];
list = ListToArray(list, delimiter);
for(i = 1; i LTE ArrayLen(list); i = i + 1)
if(NOT ListFind(returnValue, list[i], delimiter))
returnValue = ListAppend(returnValue, list[i], delimiter);
return returnValue;
}
</cfscript>
ListRemoveDuplicates() is another way to do the same thing, using the feature of structures that if you add a key to a struct that already exists it will just be overwritten.