How to replace specific characters in a string in Clojure? - string

I'm trying to replace all single quotation marks with double quotation marks in Clojure. i.e. if the string id " 'name' " I want it to become " "name" ". How can I do that?
I've been trying to use the replace function like this:
(clojure.string/replace " 'The color is red' " #"'" """)
but it is not working.

You've forgotten to escape the double quotation mark
(clojure.string/replace " 'The color is red' " #"'" "\"")

I do this so often I made some convenience functions:
quotes->double
quotes->single
You can find the details here. You may also find this template project useful, esp. the documentation list at the end.

Related

Python3: convert apostrophe unicode string

I have a string value with an apostrophe like this:
"I\\xE2\\x80\\x99m going now."
How can I get correct apostrophe value?
"I`m going now."
As you know, \xE2\x80\x99 is the a unicode character U+2019 RIGHT SINGLE QUOTATION MARK, but I have a string representation instead of byte...
Perhaps this is what you want:
utf8_apostrophe = b'\xe2\x80\x99'.decode("utf8")
str = "I"+utf8_apostrophe+"m going now"
Aside:
I ran into this when converting a single quotation mark, within a UTF-8-encoded tweet, into a normal single quote.
import re
original_tweet = 'I’m going now'
string_apostrophe = "'"
print re.sub(utf8_apostrophe, string_apostrophe, original_tweet)
which produces
I'm going now

Nested strings for text(,format) conversion

How do you use Text() with a format that has a string inside it ?
=TEXT(A1,"Comfi+"#0"(JO)";"Comfi-"#0"(JO)")
Tried """ both the inner string :
=TEXT(A1," """Comfi+"""#0"""(JO)""";"""Comfi-"""#0"(JO)""" ")
Same result with &char(34)&
Similar issue here, but I couldn't transpose the solution to my problem : How to create strings containing double quotes in Excel formulas?
Post Solution edit :
Building an almanac/calendar with the following (now fixed)formula :
=CONCATENATE(
TEXT(Format!K25,"d"),
" J+",
Format!S25,
" ",
TEXT(Format!AA25,"""Comfi+""#0""(JO)"";""Comfi-""#0""(JO)"""),
" ",
Format!AI25
)
Giving the following output in each cell :
9
J+70
Comfi+21(JO)
CRG
You've got too many quotation marks inside:
=TEXT(A1,"""Comfi+""#0""(JO)"";""Comfi-""#0""(JO)""")
You were tripling many of the inside quotation marks.
Personally, doubling up double-quotes within a quoted string is something I try to avoid at all costs. You can 'escape' the text into literals with a backslash.
=TEXT(A1,"\C\o\m\f\i+#0\(\J\O\);\C\o\m\f\i-#0\(\J\O\)")
'alternately
="Comfi"&text(a1, "+#0;-#0")&"(JO)"
Not all of those actually need to be escaped; only reserved characters. However, I usually escape them all and let Excel sort them out.

Return the quotation marks in return statement

I made a function that returns a string as shown below but I was wondering how do I keep the double quotes for the quote?
def quote_maker(quote, name, year):
''' (string, string, number)-> None
Returns a sentence displaying in what given year the
given name of a person said the given quote.
'''
return (' In '+ str(year) +', a person called '+ name +' said: '+ quote)
For example my function returns:
quote_maker("Everything should be made as simple as possible but not simpler.", "Albert Einstein", 1933)
'In 1933, a person called Albert Einstein said: Everything should be made as simple as possible but not simpler.'
Instead of: (with double quotes)
'In 1933, a person called Albert Einstein said: "Everything should be made as simple as possible but not simpler."'
You can escape characters (done with \) that have a special meaning to treat them as characters:
" this is quoted: \"example\" "
represents the string:
this is quoted: "example"
I think best way is to use string formating. And return the variable.
sentence = 'In {0}, a person called {1} said: "{2}".'.format(year, name, quote)
For complicated string you should use escape characters. For more details enter link description here

Lua string.match() problem

I want to match a few lines for a string and a few numbers.
The lines can look like
" Code : 75.570 "
or
" ..dll : 13.559 1"
or
" ..node : 4.435 1.833 5461"
or
" ..NavRegions : 0.000 "
I want something like
local name, numberLeft, numberCenter, numberRight = line:match("regex");
But I'm very new to the string matching.
This pattern will work for every case:
%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)
Short explanation: [] makes a set of characters (for example the decimals). The last to numbers use [set]* so an empty match is valid too. This way the number that haven't been found will effectively be assigned nil.
Note the difference between using + - * in patterns. More about patterns in the Lua reference.
This will match any combination of dots and decimals, so it might be useful to try and convert it to a number with tonumber() afterwards.
Some test code:
s={
" Code : 75.570 ",
" ..dll : 13.559 1",
" ..node : 4.435 1.833 5461",
" ..NavRegions : 0.000 "
}
for k,v in pairs(s) do
print(v:match('%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)'))
end
Here is a starting point:
s=" ..dll : 13.559 1"
for w in s:gmatch("%S+") do
print(w)
end
You may save these words in a table instead of printing, of course. And skip the second word.
#Ihf Thank you, I now have a working solution.
local moduleInfo, name = {};
for word in line:gmatch("%S+") do
if (word~=":") then
word = word:gsub(":", "");
local number = tonumber(word);
if (number) then
moduleInfo[#moduleInfo+1] = number;
else
if (name) then
name = name.." "..word:gsub("%$", "");
else
name = word:gsub("%$", "");
end
end
end
end
#jpjacobs Really nice, thanks too. I'll rewrite my code for synthetic reasons ;-) I'll implement your regex of course.
I have no understanding of the Lua language, so I won't help you there.
But in Java this regex should match your input
"([a-z]*)\\s+:\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?"
You have to test each group to know if there is data left, center, right
Having a look at Lua, it could look like this. No guarantee, I did not see how to escape . (dot) which has a special meaning and also not if ? is usable in Lua.
"([a-z]*)%s+:%s+([%.%d]*)?%s+([%.%d]*)?%s+([%.%d]*)?"

How can I perform a reverse string search in Excel without using VBA?

I have an Excel spreadsheet containing a list of strings. Each string is made up of several words, but the number of words in each string is different.
Using built in Excel functions (no VBA), is there a way to isolate the last word in each string?
Examples:
Are you classified as human? -> human?
Negative, I am a meat popsicle -> popsicle
Aziz! Light! -> Light!
This one is tested and does work (based on Brad's original post):
=RIGHT(A1,LEN(A1)-FIND("|",SUBSTITUTE(A1," ","|",
LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))
If your original strings could contain a pipe "|" character, then replace both in the above with some other character that won't appear in your source. (I suspect Brad's original was broken because an unprintable character was removed in the translation).
Bonus: How it works (from right to left):
LEN(A1)-LEN(SUBSTITUTE(A1," ","")) – Count of spaces in the original string
SUBSTITUTE(A1," ","|", ... ) – Replaces just the final space with a |
FIND("|", ... ) – Finds the absolute position of that replaced | (that was the final space)
Right(A1,LEN(A1) - ... )) – Returns all characters after that |
EDIT: to account for the case where the source text contains no spaces, add the following to the beginning of the formula:
=IF(ISERROR(FIND(" ",A1)),A1, ... )
making the entire formula now:
=IF(ISERROR(FIND(" ",A1)),A1, RIGHT(A1,LEN(A1) - FIND("|",
SUBSTITUTE(A1," ","|",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))))
Or you can use the =IF(COUNTIF(A1,"* *") syntax of the other version.
When the original string might contain a space at the last position add a trim function while counting all the spaces: Making the function the following:
=IF(ISERROR(FIND(" ",B2)),B2, RIGHT(B2,LEN(B2) - FIND("|",
SUBSTITUTE(B2," ","|",LEN(TRIM(B2))-LEN(SUBSTITUTE(B2," ",""))))))
This is the technique I've used with great success:
=TRIM(RIGHT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))
To get the first word in a string, just change from RIGHT to LEFT
=TRIM(LEFT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))
Also, replace A1 by the cell holding the text.
A more robust version of Jerry's answer:
=TRIM(RIGHT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(TRIM(A1))))
That works regardless of the length of the string, leading or trailing spaces, or whatever else and it's still pretty short and simple.
I found this on google, tested in Excel 2003 & it works for me:
=IF(COUNTIF(A1,"* *"),RIGHT(A1,LEN(A1)-LOOKUP(LEN(A1),FIND(" ",A1,ROW(INDEX($A:$A,1,1):INDEX($A:$A,LEN(A1),1))))),A1)
[edit] I don't have enough rep to comment, so this seems the best place...BradC's answer also doesn't work with trailing spaces or empty cells...
[2nd edit] actually, it doesn't work for single words either...
=RIGHT(TRIM(A1),LEN(TRIM(A1))-FIND(CHAR(7),SUBSTITUTE(" "&TRIM(A1)," ",CHAR(7),
LEN(TRIM(A1))-LEN(SUBSTITUTE(" "&TRIM(A1)," ",""))+1))+1)
This is very robust--it works for sentences with no spaces, leading/trailing spaces, multiple spaces, multiple leading/trailing spaces... and I used char(7) for the delimiter rather than the vertical bar "|" just in case that is a desired text item.
This is very clean and compact, and works well.
{=RIGHT(A1,LEN(A1)-MAX(IF(MID(A1,ROW(1:999),1)=" ",ROW(1:999),0)))}
It does not error trap for no spaces or one word, but that's easy to add.
Edit:
This handles trailing spaces, single word, and empty cell scenarios. I have not found a way to break it.
{=RIGHT(TRIM(A1),LEN(TRIM(A1))-MAX(IF(MID(TRIM(A1),ROW($1:$999),1)=" ",ROW($1:$999),0)))}
=RIGHT(A1,LEN(A1)-FIND("`*`",SUBSTITUTE(A1," ","`*`",LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))
New answer 9/28/2022
Considering the new excel function: TEXTAFTER (check availability) you can achieve it with a simple formula:
=TEXTAFTER(A1," ", -1)
To add to Jerry and Joe's answers, if you're wanting to find the text BEFORE the last word you can use:
=TRIM(LEFT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))))-LEN(TRIM(A1))))
With 'My little cat' in A1 would result in 'My little' (where Joe and Jerry's would give 'cat'
In the same way that Jerry and Joe isolate the last word, this then just gets everything to the left of that (then trims it back)
Copy into a column, select that column and HOME > Editing > Find & Select, Replace:
Replace All.
There is a space after the asterisk.
Imagine the string could be reversed. Then it is really easy. Instead of working on the string:
"My little cat" (1)
you work with
"tac elttil yM" (2)
With =LEFT(A1;FIND(" ";A1)-1) in A2 you get "My" with (1) and "tac" with (2), which is reversed "cat", the last word in (1).
There are a few VBAs around to reverse a string. I prefer the public VBA function ReverseString.
Install the above as described. Then with your string in A1, e.g., "My little cat" and this function in A2:
=ReverseString(LEFT(ReverseString(A1);IF(ISERROR(FIND(" ";A1));
LEN(A1);(FIND(" ";ReverseString(A1))-1))))
you'll see "cat" in A2.
The method above assumes that words are separated by blanks. The IF clause is for cells containing single words = no blanks in cell. Note: TRIM and CLEAN the original string are useful as well. In principle it reverses the whole string from A1 and simply finds the first blank in the reversed string which is next to the last (reversed) word (i.e., "tac "). LEFT picks this word and another string reversal reconstitutes the original order of the word (" cat"). The -1 at the end of the FIND statement removes the blank.
The idea is that it is easy to extract the first(!) word in a string with LEFT and FINDing the first blank. However, for the last(!) word the RIGHT function is the wrong choice when you try to do that because unfortunately FIND does not have a flag for the direction you want to analyse your string.
Therefore the whole string is simply reversed. LEFT and FIND work as normal but the extracted string is reversed. But his is no big deal once you know how to reverse a string. The first ReverseString statement in the formula does this job.
=LEFT(A1,FIND(IF(
ISERROR(
FIND("_",A1)
),A1,RIGHT(A1,
LEN(A1)-FIND("~",
SUBSTITUTE(A1,"_","~",
LEN(A1)-LEN(SUBSTITUTE(A1,"_",""))
)
)
)
),A1,1)-2)
I translated to PT-BR, as I needed this as well.
(Please note that I've changed the space to \ because I needed the filename only of path strings.)
=SE(ÉERRO(PROCURAR("\",A1)),A1,DIREITA(A1,NÚM.CARACT(A1)-PROCURAR("|", SUBSTITUIR(A1,"\","|",NÚM.CARACT(A1)-NÚM.CARACT(SUBSTITUIR(A1,"\",""))))))
Another way to achieve this is as below
=IF(ISERROR(TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14))))),TRIM(D14),TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14)))))
You can achieve this also by reversing the string and finding the first space
=MID(C3,2+LEN(C3)-SEARCH(" ",CONCAT(MID(C3,SEQUENCE(LEN(C3),,LEN(C3),-1),1))),LEN(A1))
Reverse the string
CONCAT(MID(C3,SEQUENCE(LEN(C3),,LEN(C3),-1),1))
Find the first space in the reversed string
SEARCH(" ",...
Take the position of the space found in the reversed string off the length of the string and return that portion
=MID(C3,2+LEN(C3)-SEARCH...
I also had a task like this and when I was done, using the above method, a new method occured to me: Why don't you do this:
Reverse the string ("string one" becomes "eno gnirts").
Use the good old Find (which is hardcoded for left-to-right).
Reverse it into readable string again.
How does this sound?

Resources