Replace nth occurrence of substring in string
I use simple function, which lists all occurrences, picks the nth one's position and uses it to split original string into two substrings. Then it replaces first occurrence in the second substring and joins substrings back into the new string:
import re
def replacenth(string, sub, wanted, n):
where = [m.start() for m in re.finditer(sub, string)][n-1]
before = string[:where]
after = string[where:]
after = after.replace(sub, wanted, 1)
newString = before + after
print(newString)
For these variables:
string = 'ababababababababab'
sub = 'ab'
wanted = 'CD'
n = 5
outputs:
ababababCDabababab
Notes:
The
where
variable actually is a list of matches' positions, where you pick up the nth one. But list item index starts with0
usually, not with1
. Therefore there is an-1
index andn
variable is the actual nth substring. My example finds 5th string. If you usen
index and want to find 5th position, you'll needn
to be4
. Which you use usually depends on the function, which generates ourn
.
This should be the simplest way, but maybe it isn't the most Pythonic way, because the
where
variable construction needs importingre
library. Maybe somebody will find even more Pythonic way.
Sources and some links in addition:
where
construction: How to find all occurrences of a substring?- string splitting: https://www.daniweb.com/programming/software-development/threads/452362/replace-nth-occurrence-of-any-sub-string-in-a-string
- similar question: Find the nth occurrence of substring in a string
Replacing only the nth instance of character
To replace the first instance of a character I would recommend the use of the STUFF
and CHARINDEX
functions. STUFF
inserts a string into another string. It deletes a specified length of characters in the first string at the start position and then inserts the second string into the first string at the start position.
DECLARE @str varchar(100) = '^1402 WSN NIAMLAB^teertS htimS 005'
SELECT STUFF(@str, CHARINDEX('^', @str), 1, '&')
Note that you could also use STUFF
in a query as follows:
SELECT STUFF(<yourcolumn>, CHARINDEX('^', <yourcolumn>), 1, '&')
FROM <yourtable>
Replace Nth occurrence of a character in a string with something else
You can replace ((?:\d+, ){3}\d),
with \1\n
You basically capture everything till fourth comma in group1 and comma separately and replace it with \1\n
which replaces matched text with group1 text and newline, giving you the intended results.
Regex Demo
R Code demo
gsub("((?:\\d+, ){3}\\d),", "\\1\n", "1, 2, 3, 4, 5, 6, 7, 8, 9, 10")
Prints,
[1] "1, 2, 3, 4\n 5, 6, 7, 8\n 9, 10"
Edit:
To generalize above solution to any text, we can change \d
to [^,]
New R code demo
gsub("((?:[^,]+, ){3}[^,]+),", "\\1\n", "1, 2, 3, 4, 5, 6, 7, 8, 9, 10")
gsub("((?:[^,]+, ){3}[^,]+),", "\\1\n", "a, bb, ccc, dddd, 500, 600, 700, 800, 900, 1000")
Output,
[1] "1, 2, 3, 4\n 5, 6, 7, 8\n 9, 10"
[1] "a, bb, ccc, dddd\n 500, 600, 700, 800\n 900, 1000"
stringr remove n-th occurence of a character
To remove the second occurrence only, you need to use
sub("(ab.*?)ab", "\\1", "abcdabef")
To remove the nth occurrence, use a limiting quantifier after the group where the only min
value should be equal to n-1
:
n <- 2
sub(paste0("((?:ab.*?){",n-1,"})ab"), "\\1", "abcdabef", perl=TRUE)
Note:
You need to use sub
and not gsub
since you only need a single replacement to be done.
Pattern details (when n=3
):
((?:ab.*?){2})
- Group 1 (\1
): two occurrences ofab
and any zero or more chars other than line break chars (since I am usingperl=TRUE
here, if you need multiple line matching support, add(?s)
at the start or replace.*?
with(?s:.*?)
) as few as possibleab
- anab
If you have arbitrary strings with special chars in them, you need to escape them:
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
word <- "a+(b)"
word <- regex.escape(word)
text <- "a+(b)1___a+(b)2___a+(b)3___a+(b)4"
n <- 3 # Let's remove the 3rd occurrence of a+(b)
sub(paste0("((?:", word, ".*?){",n-1,"})", word), "\\1", text, perl=TRUE)
## => [1] "a+(b)1___a+(b)2___3___a+(b)4"
See the regex demo.
Python - replace every nth occurrence of string
The code you got from the previous question is a nice starting point, and only a minimal adaptation is required to have it change every nth occurence:
def nth_repl_all(s, sub, repl, nth):
find = s.find(sub)
# loop util we find no match
i = 1
while find != -1:
# if i is equal to nth we found nth matches so replace
if i == nth:
s = s[:find]+repl+s[find + len(sub):]
i = 0
# find + len(sub) + 1 means we start after the last match
find = s.find(sub, find + len(sub) + 1)
i += 1
return s
Replacing nth occurence of a string in MySQL
In MySQLv8.0 you can use REGEXP_REPLACE()
https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-replace
REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])
So if you want to start searching from position 1 and replace only the 2nd occurence of the match you can use 1,2 as the last two options:
UPDATE `table` SET `field`=REGEXP_REPLACE(`field`,'search_string','replacement_string',1, 2);
Note:There was a bug report for MySql Version: 8.0.11 that was fixed in 8.0.12.
https://bugs.mysql.com/bug.php?id=90870
Before using in production test that you have the right MySql version and it works for you.
Replace String in between nth and n+1 occurrence of a character in Java
The better way - using regex
String input = "abc_1234_01233456_DC";
Matcher matcher = Pattern.compile("(_([^_]+)){2}").matcher(input);//{2} - number of occurrence
String result = matcher.find() ? new StringBuilder(input).replace(matcher.start(2), matcher.end(2), "78910").toString() : input; //abc_1234_78910_DC
That's it
Related Topics
Order by Month and Year in SQL with Sum
Pure-SQL Technique for Auto-Numbering Rows in Result Set
Postgresql Query to Excel Sheet
Copy Data from One Existing Row to Another Existing Row in SQL
What Is Db/Development_Structure.SQL in a Rails Project
Postgres: Select All Row with Count of a Field Greater Than 1
How to Get Referenced Values from Another Table
Count Distinct Records (All Columns) Not Working
SQL - Subquery in Aggregate Function
Check If a Variable Is Null in Plsql
Generate Series of Week Intervals for Given Month
Self-Referential Table Fields in MySQL
How to Get a Real Time Within Postgresql Transaction
Combine Multiple Rows into One Space Separated String