How to replace character 'a' with 'b' and 'b' with 'a' in a string?
You can do something like this:
var str = "blaah blaah blaah blaah";str = str.replace(/a|b/g, v => { if(v=="a"){ return "b" }else{ return "a" } }); console.log(str);
How to replace multiple substrings of a string?
Here is a short example that should do the trick with regular expressions:
import re
rep = {"condition1": "", "condition2": "text"} # define desired replacements here
# use these three lines to do the replacement
rep = dict((re.escape(k), v) for k, v in rep.iteritems())
#Python 3 renamed dict.iteritems to dict.items so use rep.items() for latest versions
pattern = re.compile("|".join(rep.keys()))
text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)
For example:
>>> pattern.sub(lambda m: rep[re.escape(m.group(0))], "(condition1) and --condition2--")
'() and --text--'
Javascript: Replace all occurences of ' a ' in a string with ' b ' with a regex
Use a lookahead after " a" to match overlapping substrings:
/ a(?= )/g
Or, to match any whitespace, replace spaces with \s
.
The lookahead, being a zero-width assertion, does not consume the text, so the space after " a" will be available for the next match (the first space in the pattern is part of the consuming pattern).
See the regex demo
var regex = / a(?= )/g;var strs = ['x a y a x', 'x a a a x', 'x aa x'];for (var str of strs) { console.log(str,' => ', str.replace(regex, " b"));}
Substitute part of a word in a string by the number of characters
You may use gsubfn
to be able to manipulate capture groups:
> library(gsubfn)
> gsubfn("\\y([a-z])([a-z]+)([a-z])", function(x,y,z) paste0(x,nchar(y),z),"this is a test string")
[1] "t2s is a t2t s4g"
Note that \y
is a word boundary (equivalent of \b
) in Tcl regex patterns (gsubfn
uses Tcl regex library by default). You may also use perl=TRUE
to use \b
:
> gsubfn("\\b([a-z])([a-z]+)([a-z])", function(x,y,z) paste0(x,nchar(y),z),"this is a test string", perl=TRUE)
[1] "t2s is a t2t s4g"
Note that the capturing group values are passed to the anonynous replacement function via x
(=\1
), y
(=\2
) and z
(=\3
).
Best way to replace multiple characters in a string?
Replacing two characters
I timed all the methods in the current answers along with one extra.
With an input string of abc&def#ghi
and replacing & -> \& and # -> \#, the fastest way was to chain together the replacements like this: text.replace('&', '\&').replace('#', '\#')
.
Timings for each function:
- a) 1000000 loops, best of 3: 1.47 μs per loop
- b) 1000000 loops, best of 3: 1.51 μs per loop
- c) 100000 loops, best of 3: 12.3 μs per loop
- d) 100000 loops, best of 3: 12 μs per loop
- e) 100000 loops, best of 3: 3.27 μs per loop
- f) 1000000 loops, best of 3: 0.817 μs per loop
- g) 100000 loops, best of 3: 3.64 μs per loop
- h) 1000000 loops, best of 3: 0.927 μs per loop
- i) 1000000 loops, best of 3: 0.814 μs per loop
Here are the functions:
def a(text):
chars = ""
for c in chars:
text = text.replace(c, "\\" + c)
def b(text):
for ch in ['&','#']:
if ch in text:
text = text.replace(ch,"\\"+ch)
import re
def c(text):
rx = re.compile('([])')
text = rx.sub(r'\\\1', text)
RX = re.compile('([])')
def d(text):
text = RX.sub(r'\\\1', text)
def mk_esc(esc_chars):
return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('')
def e(text):
esc(text)
def f(text):
text = text.replace('&', '\&').replace('#', '\#')
def g(text):
replacements = {"&": "\&", "#": "\#"}
text = "".join([replacements.get(c, c) for c in text])
def h(text):
text = text.replace('&', r'\&')
text = text.replace('#', r'\#')
def i(text):
text = text.replace('&', r'\&').replace('#', r'\#')
Timed like this:
python -mtimeit -s"import time_functions" "time_functions.a('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.b('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.c('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.d('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.e('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.f('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.g('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.h('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.i('abc&def#ghi')"
Replacing 17 characters
Here's similar code to do the same but with more characters to escape (\`*_{}>#+-.!$):
def a(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
text = text.replace(c, "\\" + c)
def b(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
if ch in text:
text = text.replace(ch,"\\"+ch)
import re
def c(text):
rx = re.compile('([])')
text = rx.sub(r'\\\1', text)
RX = re.compile('([\\`*_{}[]()>#+-.!$])')
def d(text):
text = RX.sub(r'\\\1', text)
def mk_esc(esc_chars):
return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('\\`*_{}[]()>#+-.!$')
def e(text):
esc(text)
def f(text):
text = text.replace('\\', '\\\\').replace('`', '\`').replace('*', '\*').replace('_', '\_').replace('{', '\{').replace('}', '\}').replace('[', '\[').replace(']', '\]').replace('(', '\(').replace(')', '\)').replace('>', '\>').replace('#', '\#').replace('+', '\+').replace('-', '\-').replace('.', '\.').replace('!', '\!').replace('$', '\$')
def g(text):
replacements = {
"\\": "\\\\",
"`": "\`",
"*": "\*",
"_": "\_",
"{": "\{",
"}": "\}",
"[": "\[",
"]": "\]",
"(": "\(",
")": "\)",
">": "\>",
"#": "\#",
"+": "\+",
"-": "\-",
".": "\.",
"!": "\!",
"$": "\$",
}
text = "".join([replacements.get(c, c) for c in text])
def h(text):
text = text.replace('\\', r'\\')
text = text.replace('`', r'\`')
text = text.replace('*', r'\*')
text = text.replace('_', r'\_')
text = text.replace('{', r'\{')
text = text.replace('}', r'\}')
text = text.replace('[', r'\[')
text = text.replace(']', r'\]')
text = text.replace('(', r'\(')
text = text.replace(')', r'\)')
text = text.replace('>', r'\>')
text = text.replace('#', r'\#')
text = text.replace('+', r'\+')
text = text.replace('-', r'\-')
text = text.replace('.', r'\.')
text = text.replace('!', r'\!')
text = text.replace('$', r'\$')
def i(text):
text = text.replace('\\', r'\\').replace('`', r'\`').replace('*', r'\*').replace('_', r'\_').replace('{', r'\{').replace('}', r'\}').replace('[', r'\[').replace(']', r'\]').replace('(', r'\(').replace(')', r'\)').replace('>', r'\>').replace('#', r'\#').replace('+', r'\+').replace('-', r'\-').replace('.', r'\.').replace('!', r'\!').replace('$', r'\$')
Here's the results for the same input string abc&def#ghi
:
- a) 100000 loops, best of 3: 6.72 μs per loop
- b) 100000 loops, best of 3: 2.64 μs per loop
- c) 100000 loops, best of 3: 11.9 μs per loop
- d) 100000 loops, best of 3: 4.92 μs per loop
- e) 100000 loops, best of 3: 2.96 μs per loop
- f) 100000 loops, best of 3: 4.29 μs per loop
- g) 100000 loops, best of 3: 4.68 μs per loop
- h) 100000 loops, best of 3: 4.73 μs per loop
- i) 100000 loops, best of 3: 4.24 μs per loop
And with a longer input string (## *Something* and [another] thing in a longer sentence with {more} things to replace$
):
- a) 100000 loops, best of 3: 7.59 μs per loop
- b) 100000 loops, best of 3: 6.54 μs per loop
- c) 100000 loops, best of 3: 16.9 μs per loop
- d) 100000 loops, best of 3: 7.29 μs per loop
- e) 100000 loops, best of 3: 12.2 μs per loop
- f) 100000 loops, best of 3: 5.38 μs per loop
- g) 10000 loops, best of 3: 21.7 μs per loop
- h) 100000 loops, best of 3: 5.7 μs per loop
- i) 100000 loops, best of 3: 5.13 μs per loop
Adding a couple of variants:
def ab(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
text = text.replace(ch,"\\"+ch)
def ba(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
if c in text:
text = text.replace(c, "\\" + c)
With the shorter input:
- ab) 100000 loops, best of 3: 7.05 μs per loop
- ba) 100000 loops, best of 3: 2.4 μs per loop
With the longer input:
- ab) 100000 loops, best of 3: 7.71 μs per loop
- ba) 100000 loops, best of 3: 6.08 μs per loop
So I'm going to use ba
for readability and speed.
Addendum
Prompted by haccks in the comments, one difference between ab
and ba
is the if c in text:
check. Let's test them against two more variants:
def ab_with_check(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
if ch in text:
text = text.replace(ch,"\\"+ch)
def ba_without_check(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
text = text.replace(c, "\\" + c)
Times in μs per loop on Python 2.7.14 and 3.6.3, and on a different machine from the earlier set, so cannot be compared directly.
╭────────────╥──────┬───────────────┬──────┬──────────────────╮
│ Py, input ║ ab │ ab_with_check │ ba │ ba_without_check │
╞════════════╬══════╪═══════════════╪══════╪══════════════════╡
│ Py2, short ║ 8.81 │ 4.22 │ 3.45 │ 8.01 │
│ Py3, short ║ 5.54 │ 1.34 │ 1.46 │ 5.34 │
├────────────╫──────┼───────────────┼──────┼──────────────────┤
│ Py2, long ║ 9.3 │ 7.15 │ 6.85 │ 8.55 │
│ Py3, long ║ 7.43 │ 4.38 │ 4.41 │ 7.02 │
└────────────╨──────┴───────────────┴──────┴──────────────────┘
We can conclude that:
Those with the check are up to 4x faster than those without the check
ab_with_check
is slightly in the lead on Python 3, butba
(with check) has a greater lead on Python 2However, the biggest lesson here is Python 3 is up to 3x faster than Python 2! There's not a huge difference between the slowest on Python 3 and fastest on Python 2!
Java: replacement in a string according to multiple rules
Here is an algorithm you can use:
Assumption: String consists of only (A,B,C)
If string is composed of B's
only (no A/C), output = input string.
Otherwise:
Divide the string in the following way. If a substring consists of (B,A) or (B,C), divide them. Replace with A and C respectively. That will be the answer.
eg. Let the string be: "BBBAABABBBCCBCBBCACB". This will be divided as:
"BBBAABABBB" "CCBCBBC" "A" "CB"
And this will result in output string as: ACAC
Basically, just ignore all B's
and replace clusters of A's
with A
and clusters of C's
with C
.
How to replace two things at once in a string?
When you need to swap variables, say x and y, a common pattern is to introduce a temporary variable t to help with the swap: t = x; x = y; y = t
.
The same pattern can also be used with strings:
>>> # swap a with b
>>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b')
'oabmb'
This technique isn't new. It is described in PEP 378 as a way to convert between American and European style decimal separators and thousands separators (for example from 1,234,567.89
to 1.234.567,89
. Guido has endorsed this as a reasonable technique.
How to use replace(char, char) to replace all instances of character b with nothing
There's also a replaceAll function that uses strings, note however that it evals them as regexes, but for replacing a single char will do just fine.
Here's an example:
String meal = "Hambbburger";
String replaced = meal.replaceAll("b","");
Note that the replaced
variable is necessary since replaceAll
doesn't change the string in place but creates a new one with the replacement (String
is immutable in java).
If the character you want to replace has a different meaning in a regex (e.g. the .
char will match any char, not a dot) you'll need to quote
the first parameter like this:
String meal = "Ham.bur.ger";
String replaced = meal.replaceAll(Pattern.quote("."),"");
Related Topics
How to Adjust the Font Size of Tablegrob
R - Scaling Numeric Values Only in a Dataframe with Mixed Types
Calling Library() in R with a Variable as the Argument
R Crashing While Displaying Ggplot After Update (Process Memory Read Out of Range)
If Column Contains String Then Enter Value for That Row
Rcurl: Http Authentication When Site Responds with Http 401 Code Without Www-Authenticate
Converting a "Map" Object to a "Spatialpolygon" Object
Select Columns by Class (E.G. Numeric) from a Data.Table
Check to See If a Value Is Within a Range
Create and Call Linear Models from List
How to Import Only One Function from Another Package, Without Loading the Entire Namespace
Change Background Color of Networkd3 Plot
Ggplot2 and Geom_Density: How to Remove Baseline
Adding Slight Curve (Or Bend) in Ggplot Geom_Path to Make Path Easier to Read