I was going through the Search Function syntax and examples as per the following Office support document here.
Although the overall steps are clear as per the image attached here, one specific portion
SEARCH("""",A2,SEARCH("""",A2)+1)
is not quite clear to me. Could someone explain how it leads to 10 in the results?
It leads to 10 because it is counting from the beginning as in the first search function. The only difference is that you are searching for the second ". The first " is the fifth character in the sentence, while the second is the tenth. You are still looking at the same cell, same characters.
If you want to start the count after the first " is located, you can look at the right part following the first quotation.
SEARCH("""",RIGHT(A2,LEN(A2)-SEARCH("""",A2)))
It just finds the second occurrence of the double quotation mark. This is the simplest way to do such things, because SEARCH only finds the first occurrence and returns its position.
SEARCH() finds the position of the requested character, in this case a quotation mark. The embedded second SEARCH() gives the first search a new start position, which is after the first quotation mark at position 10. Since it is starting at location 10 + 1, the next occurrence of a quotation mark is at position 24.
Related
In the image, 'muddle' is the string containing junk words and the strings I want to extract. There is a fixed list of junk words - the good strings could be literally anything.
You can see this formula has correctly extracted "moo" and "coo", which are not in the list of junk words. The formula is below.
=LET(junkStart,FILTER(SEARCH(Table1[junkwords],Table2[muddle]),ISNUMBER(SEARCH(Table1[junkwords],Table2[muddle]))),
junkEnd,FILTER(SEARCH(Table1[junkwords],Table2[muddle])+LEN(Table1[junkwords])-1,ISNUMBER(SEARCH(Table1[junkwords],Table2[muddle])+LEN(Table1[junkwords])-1)),
goodstart,FILTER(junkEnd+1,(junkEnd+1<=LEN(Table2[muddle]))*(ISERROR(XMATCH(junkEnd+1,junkStart)))),
goodend,FILTER(junkStart-1,(junkStart-1>=LEN(1))*(ISERROR(XMATCH(junkStart-1,junkEnd))))+1,
goodchars,goodend-goodstart,
TEXTJOIN("; ",TRUE,MID(Table2[muddle],goodstart,goodchars)))
This works well, but it falls down if a junk word occurs more than once. See below.
The only difference is that 'woo' occurs twice in the second example.
I need a single cell solution. VBA is not an option for me. Using the name manager would be untidy, as would nested formulas.
I've got this far with formulas, which as far as I can tell is the furthest anyone has got with the 'removing multiple words from a cell' problem. I can see the issue - once SEARCH locates the start of a string in a cell, it doesn't go looking for a second occurrence of that string. But I don't know how to find the start of every instance of every string. Can anyone help?
REDUCE is perfect for this:
=REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(m,j,SUBSTITUTE(m,j,"")))
REDUCE starts at the Table2[muddle] value as m then it substitutes the first value of Table1[junkwords] j with "" the outcome becomes the new m which will get a substitute of the second value of j. The result will be the new m, etc.
If you would want to have it comma separated it becomes more complicated, but you can realize by:
=LET(t,SUBSTITUTE(","&REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y,",")))&",",",,",","),
MID(t,2,LEN(t)-3))
This does almost the same as the previous solution, but instead of substituting for blanks it substitutes for , and substitutes all duplicate ,, for singles, so if more substitutes followed eachother it results in one comma. Also, if the first and/or last part got substituted by a single ,, then the result would have a leading and/or trailing ,. This is solved by first adding , in the front and back before substituting the double comma's for singles. the result t is then wrapped in MID, where the first and last character (both being a ,) are removed.
Alternate solution:
=LET(t,REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y," "))),
SUBSTITUTE(TRIM(t)," ",","))
Or in one go if you don't want to use LET:
=SUBSTITUTE(TRIM(REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y," "))))," ",",")
This replaces the junk words with a space. Regardless how many junk words in between words or how many trailing or leading spaces TRIM will fix it to the words separated by one space only. Substituting the spaces for comma gets to your result.
There's no single-formula solution if the junkwords list is not fixed.
Instead, you may choose to use the Substitute() function on each cell of the "Extracted Strings" column to substitute all occurances of each junk word in muddle, i.e. substitute "boo" muddle, then substitute "voo" in the resulted string, replace "noo" in the resulted string...so on. You will get the last cell.
One point to note though, you need to ensure no substring / partial strings problem in the junkwords or you need to define the rules of processing in order for the solution to be "complete". Consider the followings:
junk words = abc, def, cde
muddle = 1234abcdef5678
if you process the string in the above order, you got "12345678"
if you process the junk words in reverse order, you got "123abf5678"
Please help, i'm looking to reference a portion of my file name in an excel cell, see below example:
File name: 000_XYZ_ABC_DEF ; I need to reference the ABC portion (but this won't be limited to only 3 letters as this varies) - is there a formula I could use that would cater for the variance as well as only referencing this portion?
thank you
In B1, formula copied down :
=TRIM(LEFT(RIGHT(SUBSTITUTE(A1,"_",REPT(" ",30)),60),30))
Well, very brutal with MID() and FIND() but works:
Basic explanation is that MID() takes the characters from a string from the start points and end point you define.
The use of find() is to locate the second underscore which is the start point (plus 1 though) and the position of the 3rd underscore which with the position of the second gives the number of characters to return.
It will be good practice to take it all apart.
Edit: I have added the complete function, so that you can copy it directly:
=MID(A1,FIND("_",A1,FIND("_",A1,1)+1)+1,FIND("_",A1,FIND("_",A1,FIND("_",A1,1)+1)+1)-FIND("_",A1,FIND("_",A1,1)+1)-1)
In your comment you have not included in your function the "_" which is the precise bits of the text FIND() is looking for. Compare mine to yours from your comment:
=MID(A1,FIND("",A1,FIND("",A1,1)+1)+1,FIND("",A1,FIND("",A1,FIND("",A1,1)+1)+1)-FIND("",A1,1)+1)-1
I've been trying a few different ways to try and search and replace on excell to remove the last couple of characters.
For instance in one column I have product name S
I want to remove the " S" only.
I have tried some if formulas a swell and not had much luck. I'm assuming there is a simple regex that can be used for the search and replace e.g. " S/" that would just replace if its the last characters and has nothing after it.
Try using the SUBSTITUTE function and replace the letters you want to remove with a unique character/ word / space not appearing anywhere else in the booklet, depending on which part of the string you're trying to remove and what format you're trying to keep
then find and replace ( CTRL +F) that word with the black (space) character
see how to use SUBSTITUTE function here:
https://exceljet.net/excel-functions/excel-substitute-function
Since you are only interested in the end of the string, I don't think you need regex or anything too sophisticated.
If I understand correctly, you want to get the original string (product name S) up until but not including something that appears at the end (S). This means that in your example, you want the 12 leftmost digits: the digits of the original string (14) minus the digits of the pattern (2) - this would give you product name. If the original string does not end with the pattern, you want the original string.
Therefore, I suggest the following:
=IF(RIGHT("original string",LEN("pattern"))="pattern",
LEFT("original string",LEN("original string")-LEN("pattern")),
"original string")
Check these examples:
I am translating a game, and the game's text box only supports 50 characters max per line. Is there a way to use a formula to split the entire sentence every 50 characters or whole word (49, 48, 47, etc)?
I am currently working with this formula.
=JOIN(CHAR(10),SPLIT(REGEXREPLACE(A1, "(.{50})", "/$1"),"/"))
The problem with this code, is that it splits at exactly 50 characters (one time), and will split in the middle of the word.
So again, my goal is to have it not split on the 50th character IF the 50th character is in the middle of the word, and for the rule to apply for the rest of the lines too because it only applies on the first line.
Please take a look at this test google sheet to get an example of what I am talking about.
If it's impossible to do it on Google Sheets, I don't mind moving to Excel provided I get a functioning code.
For the record, I did ask in Google's product forums 2 days ago, and still haven't received an answer.
=REGEXREPLACE(A1, "(.{1,50})\b", "$1" & CHAR(10))
{50} matches exactly 50 times, but what you need is 50 or less.
\b is word boundary that matches between alphanumeric and non-alphanumeric character.
= REGEXEXTRACT(A1,"(?ism)^"&REPT("([\w\d'\(\),. ]{0,49}\s)", ROUNDUP(LEN(A1)/50,0))&"([\w\d'\(\),. ]{0,49})$")
Tested with various expressions and works as intended. Note that only these characters [a-zA-Z0-9_'(),.] are allowed, Which means - and other characters not mentioned will not work. If you need them, add them inside the REPT expression and finishing regexp formula. Otherwise, This will work perfectly.
You are pretty close. I'm not an expert in Sheets, so not sure if this is the best way, but your Regex is wrong for what you want.
Also, you need to be certain that you don't use a split character that might appear in the phrase itself. However, using CHAR(10) for the replace character allows you to insert LF without going through the JOIN SPLIT sequence.
replace any line feeds, carriage returns and spaces with a single space
Match strings that start with a non-Space character followed by up to 49 more characters which are followed by a space or the end of the string.
replace the capture group with the capturing group followed by the CHAR(10) (and delete the space following).
There will be extra CHAR(10) at the end which you can strip off.
EDIT Regex changed slightly due to a difference in behavior between Google's RE and what I am used to (probably has to do with how a non-backtracking regex works). The problem showed up on your example:
=regexreplace(REGEXREPLACE(REGEXREPLACE(A1 & " ","[\r\n\s]+"," "),"(\S.{0,49})\s","$1" & char(10)),"\n+\z","")
How can I find() the location of the Nth occurrence of a word in a sentence in a cell?
Example:
Humpty Dumpty sat on a wall. Humpty had a great fall.
In above i want to find the total occurrences and the location of the word 'Humpty'.
Expected Result:
Occurances location
1 1
2 30
Is there any way in which I can know the above?
I want to use the location of the 2nd occurrence and calculate further if there are more than 2 occurrences of the target word.
Thanks!
Without using vba you can use this formula:
=IFERROR(FIND($B$2,$B$1,1+IFERROR(VALUE(B4),0)),"not found")
Which basically says:
Find the target (Humpty) in the sample text (Humpty dumpty etc..) and start searching from the next position to the last found. If no more target text is found, return not found. The IFERROR(VALUE(B4),0)) prevents an error for the first search which should always start from position 1, but needs to ignore the fact it is checking the location label.
Here's a screenshot of the implementation:
Another solution:
=IFERROR(FIND("###",SUBSTITUTE($A$1,$B$4,"###",$A6)),"")
See image for reference: