I’m working on a Google Sheet for work (not allowed to share), and I want to create an Apps Script Function that parses through all the data and erases cell content if they contain “?”, “PPS”, “LES”, “MPES”,or “PSPEC”. I can’t find any way to do it without deleting the whole row, which i don’t want. Any help will be greatly appreciated, thank you.
function delIfContains() {
const contains = ["?","PPSF","LES","MPES","PSPEC"];//needles
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();//haystack
contain.forEach(s => {
sh.createTextFinder(s).matchEntireCell(false).findAll().forEach(rg => rg.clearContent());//reaper
});
}
textFinder
Cooper already showed how to do this with a loop that creates a TextFinder for value separately. To match all values in one go, use a regular expression, like this:
function test() {
const range = SpreadsheetApp.getActiveSheet().getDataRange();
const regexString = '\\?|PPS|LES|MPES|PSPEC';
const numCleared = clearMatchingCells_(range, regexString);
SpreadsheetApp.getActive().toast(`Cleared ${numCleared} cell(s).`);
}
/**
* Clears cells in a range that match a regular expression.
*
* #param {SpreadsheetApp.Range} range The range to search.
* #param {String} regexString The pattern to match with cells in range.
*/
function clearMatchingCells_(range, regexString) {
const matches = range
.createTextFinder(regexString)
.useRegularExpression(true)
.findAll();
matches.forEach(cell => cell.clearContent());
return matches.length;
}
Note that any regex special characters such as ? and * need to be double escaped in regexString.
As another approach, how about using replaceAllWith with TextFinder as follows?
Sample script:
function myFunction() {
const search = ["\\?", "PPS", "LES", "MPES", "PSPEC"];
const r = search.map(e => `.*${e}.*`).join("|");
SpreadsheetApp.getActiveSheet().getDataRange().createTextFinder(r).useRegularExpression(true).replaceAllWith("");
}
When this script is run, the cell values including search are replaced with "".
Reference:
replaceAllWith(replaceText)
Related
Main Goals
Retrieve string from google sheets tab.
Edit string to remove "s and ,s.
re-format the string for upload into google sheets.
I have accomplished the first 2 tasks of my goal. Although I will explain in full the situation.
I am querying google sheets to return a row which contains a specified string so it can be added to a new sheet. currently I have been able to retrieve the row fine. the data comes back looking like this.
"12/24/2020, 3:40:33 PM","SanguineDepths+5","The Key Is
Timed","1000","Aegwynn","#name #name #name #[Manager]
name-name","name#0000 name#0000 name#0000
name#0000","Advertiser-Realm","testing-testing","Ticket","33p2bdlfto9g45","Customer-Realm","Horde",""
I have then used the following code to remove all of the "s and ,s.
const result = `"12/24/2020, 3:40:33 PM","SanguineDepths+5","The Key Is Timed","1000","Aegwynn","#name #name #name #[Manager] name-name ","name#0000 name#0000 name#0000 name#0000","Advertiser-Realm","testing-testing","Ticket","33p2bdlfto9g45","Customer-Realm","Horde",""`
var result1 = result.replace (/,/g, " ");
var result2 = result1.replace (/"/g, "");
Now my string is looking like this.
12/24/2020 3:40:33 PM SanguineDepths+5 Timed 1000 Aegwynn #name #name
#name #[Manager] name-name name#0000 name#0000 name#0000
name#0000 Advertiser-Realm testing-testing Ticket 33p2bdlfto9g45
Customer-Realm Horde
When uploading the above string which removes the characters I do not require, google sheets actually inputs all of the data in one cell instead of multiple, is there a way I can fix this? I did try to use arguments although I would like the 4 discord name#0000 in one cell and the 4 discord #name also in their own cell, like this.
Desired format for data to be entered in
So my main goal is to format the result in such a way I can write them to google sheets in their own cells.
Edit #1
I have used the .split(',') function but google API returns the following error:
"The API returned an error: Error: Invalid values[1][0]: list_value"
You could try to target the comma's in between to split the data at that point to an array and then take care of removing charcters.
Try:
result.split(',')
That should give you an Array.
And you could resuse your code to take out the characters you don't need with an array helper: something like:
result.split(',').map((part) => {
return part.replace (/"/g, "")
})
I was hoping for an easier solution, but I ended up using this method with multiple arguments for the string I got back from the sheet.
var result1 = result.replace (/,/g, " ");
var result2 = result1.replace (/"/g, "");
const argsRUN = result2.split(' ');
const command = argsRUN.shift().toLowerCase();
var date1 = (argsRUN[0]);
var time1 = (argsRUN[1]);
var ampm = (argsRUN[2]);
var dungeonkey = (argsRUN[3]);
var timedornot = (argsRUN[4]);
var costofboost = (argsRUN[5]);
var paymentrealm1 = (argsRUN[6]);
var boost1ID = (argsRUN[7]);
var boost2ID = (argsRUN[8]);
var boost3ID = (argsRUN[9]);
var boost4ID = (argsRUN[10]);
var boost1tag = (argsRUN[11]);
var boost2tag = (argsRUN[12]);
var boost3tag = (argsRUN[13]);
var boost4tag = (argsRUN[14]);
var advertiserrealm = (argsRUN[15]);
var commentup = (argsRUN[16]);
var ticketornot = (argsRUN[17]);
var uniquerunid = (argsRUN[18]);
var customerrealm = (argsRUN[19]);
var customerfaction = (argsRUN[20]);
I'm trying to replace the user flags with emojis but I have no idea how to do it.
I tried that but it didn't work
const flags = {
"HOUSE_BRILLIANCE":"<:house_brilliance:773066280303198218>",
"HOUSE_BRAVERY":"<:house_bravery:773066279967522868>",
"HOUSE_BALANCE":"<:house_balance:773066280319057930>",
"EARLY_SUPPORTER":"<:early_supporter:773066280416444466>",
"HYPESQUAD_EVENTS":"<:hypesquad_events:773066279892418613>",
"BUGHUNTER_LEVEL_1":"<:bughunter:773066280269512714>",
"BUGHUNTER_LEVEL_2":"<:bughunter:773066280269512714>",
"DISCORD_EMPLOYEE":"<:early_verified_bot_developer:773066280135688212>",
"PARTNERED_SERVER_OWNER":"<:partnered_server_owner:773066279996751872>",
"TEAM_USER":"",
"SYSTEM":"",// tf is this one
}
let mflags = message.mentions.users.first().flags.toArray().join(' ')
let fres = mflags.replace(/#(\w+)/g, (match,key)=>flags[key]||match);```
The initial string:
initString = '/digital/collection/music/bunch/of/other/stuff'
What I want: music
Specifically, I want any term (will never include slashes) that would come between collection/ and /bunch
How I'm going about it:
if(initString.includes('/digital/collection/')){
let slicedString = initString.slice(19); //results in 'music/bunch/of/other/stuff'
let indexOfSlash = slicedString.indexOf('/'); //results, in this case, to 5
let desiredString = slicedString.slice(0, indexOfSlash); //results in 'music'
}
Question:
How the heck do I accomplish this in javascript in a more elegant way?
I looked for something like an endIndexOf() that would replace my hardcoded .slice(19)
lastIndexOf() isn't what I'm looking for, because I want the index at the end of the first instance of my substring /digital/collection/
I'm looking to keep the number of lines down, and I couldn't find anything like a .getStringBetween('beginCutoff, endCutoff')
Thank you in advance!
your title says "index" but your example shows you wanting to return a string. If, in fact, you are wanting to return the string, try this:
if(initString.includes('/digital/collection/')) {
var components = initString.split('/');
return components[3];
}
If the path is always the same, and the field you want is the after the third /, then you can use split.
var initString = '/digital/collection/music/bunch/of/other/stuff';
var collection = initString.split("/")[2]; // third index
In the real world, you will want to check if the index exists first before using it.
var collections = initString.split("/");
var collection = "";
if (collections.length > 2) {
collection = collections[2];
}
You can use const desiredString = initString.slice(19, 24); if its always music you are looking for.
If you need to find the next path param that comes after '/digital/collection/' regardless where '/digital/collection/' lies in the path
first use split to get an path array
then use find to return the element whose 2 prior elements are digital and collection respectively
const initString = '/digital/collection/music/bunch/of/other/stuff'
const pathArray = initString.split('/')
const path = pathArray.length >= 3
? pathArray.find((elm, index)=> pathArray[index-2] === 'digital' && pathArray[index-1] === 'collection')
: 'path is too short'
console.log(path)
Think about this logically: the "end index" is just the "start index" plus the length of the substring, right? So... do that :)
const sub = '/digital/collection/';
const startIndex = initString.indexOf(sub);
if (startIndex >= 0) {
let desiredString = initString.substring(startIndex + sub.length);
}
That'll give you from the end of the substring to the end of the full string; you can always split at / and take index 0 to get just the first directory name form what remains.
You can also use regular expression for the purpose.
const initString = '/digital/collection/music/bunch/of/other/stuff';
const result = initString.match(/\/digital\/collection\/([a-zA-Z]+)\//)[1];
console.log(result);
The console output is:
music
If you know the initial string, and you have the part before the string you seek, then the following snippet returns you the string you seek. You need not calculate indices, or anything like that.
// getting the last index of searchString
// we should get: music
const initString = '/digital/collection/music/bunch/of/other/stuff'
const firstPart = '/digital/collection/'
const lastIndexOf = (s1, s2) => {
return s1.replace(s2, '').split('/')[0]
}
console.log(lastIndexOf(initString, firstPart))
I'm getting coordinates via jQuery like this and fill them into a form:
$('#location').val(pos);
The problem is that the value is filled in like this:
(40.00000, 150.00000)
How do I extract them from the brackets and "split" them into latitude & longitude values like:
pos_lat = 40.00000;
pos_long = 150.00000;
https://jsfiddle.net/ojcoj74y/
var pos = "(40.00000, 150.00000)";
var pos_segs = pos.slice(1,-1).split(', ');
var pos_lat = pos_segs[0];
var pos_long = pos_segs[1];
UPDATE:
Thanks! Is it possible to run this within a function, too? –
user1996496 1 hour ago
https://jsfiddle.net/ojcoj74y/1/
function getPos(strPos) {
var pos_segs = strPos.slice(1, -1).split(', ');
return {
posLat: pos_segs[0],
posLong: pos_segs[1]
};
}
Remove brackets and empty space and then split by comma. Finally (if you need) parse strings to floats:
positionString.replace(/\(|\)|\s/g, '').split(',')).map(parseFloat);
I am currently working on a project that will allow me to bring in a string that would have a designated token that I will grab, get the designated value and remove the token and push to an array. I have the following condition which I am using split in JavaScript but it is not splitting on the designated ending token.
This is the beginning string
"~~/Document Heading 1~~<div>This is a test <b>JUDO</b> TKD</div>~~end~~<div class="/Document Heading 1">This is a test <b>JUDO</b> TKD</div>"
Current Code Block
var segmentedStyles = [];
var contentToInsert = selectedContent.toString();
var indexValue = selectedContent.toString().search("~~");
if (indexValue <= 0) {
var insertionStyle = contentToInsert.split("~~");
segmentedStyles.push(insertionStyle);
}
The designated token is enclosed by a "~~ .... ~~". In this code Block it is going through the condition but the string it is not splitting correctly. I am currently getting the Following string pushed to my array.
This is my current result
[,/Document Heading 1<div>This is a test <b>JUDO</b> TKD</div>end,
<div class="/Document Heading 1">This is a test <b>JUDO</b> TKD</div>]
My Goal
I would like to split a string that is coming in if a token is present. For example I would like to split a string starting from ~~.....~~ through ~~end~~. The array should hold two values like the following
segmentedStyles = [<div>This is a test <b>JUDO</b> TKD</div>],[<div class="/Document Heading 1">This is a test <b>JUDO</b> TKD</div>]
You could use a regular expression for matching the parts.
var string = '~~/Document Heading 1~~<div>This is a test <b>JUDO</b> TKD</div>~~end~~<div class="/Document Heading 1">This is a test <b>JUDO</b> TKD</div>',
array = string.split('~~').filter(function (_, i) {
return i && !(i % 2); // just get element 2 and 4 or all other even indices
});
console.log(array);
Assuming the string always starts with ~~/ you could use the following regex to get the array you want
~~([^\/].*)~~end~~(.*)
https://regex101.com/r/hJ0vM4/1
I honestly didn't quite understand what you're trying to accomplish haha, but I sort of understood what you're trying to do :)
First, just trying to make it clear some stuff. If you split() your string using /~~/ as the Regular Expression for splitting you'll get all the bits surrounded by "~~" in an array, like you did.
Second, if you change the tokens to ~~START~~ and ~~END~~ (tokens that never change) you can accomplish what you want by simply doing string.split(/~~(START|END)~~/) - Much shorter and quicker ;)
Third is the string always in the format ~~<something>~~THE STUFF YOU WANT~~end~~MORE STUFF YOU WANT? If it is, I'd suggest doing this:
function splitTheTokens(str) {
var result = [];
var parts = str.split(/~~end~~/);
for (var i = 0; i < parts.length; i++) {
if (!parts[i]) { continue; } // Skips blanks
if (parts[i].indexOf("~~") == 0) {
// In case you want to do something with the name thing:
var thisPartName = parts[i].substring(2, parts[i].indexOf("~~", 2));
// What (I think) you actually want
var thisPartValue = parts[i].substring(thisPartName.length + 4);
result.push(thisPartValue);
}
else {
result.push(parts[i]);
}
}
return result;
}
Hope this helps :D