2

With reference to this SO question: Cutting a string at nth occurrence of a character

Have a slightly different question: Can this be done using regex?

"aa.bb.cc.dd.ee.xx" => "aa.bb.NN.dd.ee.ff" 
(replacing only 3rd occurrence, all chars are random alphanumeric text )

NOTE: .split() .slice() .join() is a readable solution, regex seems possible and straightforward (I may be wrong). Eg: replacing the first two "aa." and "bb." with say 'AoA' and 'BoB', seems trivial:-

`"aa.bb.cc.dd.ee.xx".replace(/([^\.]*\.){2}/, 'AoA.BoB.')`

Edit: Since "." means 'matching anything' in regex, please use ";" (semicolon) instead. To make it more difficult, what if we have a string like this:

"ax;;cyz;def;eghi;xyzw" and we wanted to replace 3rd section (eg: cyz)

Community
  • 1
  • 1
Alvin K.
  • 4,329
  • 20
  • 25
  • NOTE: Personally all 3 answers are acceptable, just that SO only allows 1 acceptable answer *grumble*. **Readers** Do add +1 to the answer(s) that suits you best. – Alvin K. May 02 '14 at 16:50

3 Answers3

3

To replace the 3rd occurence, you would match:

^((\w{2}\.){2})\w{2}\.(.*)$

and replace with:

\1NN.\3

To replace the n-th occurence, you would match:

^((\w{2}\.){n-1})\w{2}\.(.*)$

Demo

For your comment:

^(([^;]*\;){2})[^;]*\;(.*)$

Demo2

sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • If I have random chars like `%23;B;ccc;123;efgh;`, then \w{2} match will fail. Nevertheless, good solution for fixed 2 letter char. – Alvin K. May 02 '14 at 05:57
  • @AlvinK., I have updated my answer for your second case. If it helped, would you mind accepting it? Thank you. – sshashank124 May 02 '14 at 05:59
  • sshashank124: Demo2 is correct, however @Ulugbek posted his code first, hence I have given him the credits. To note: Demo2 regex uses 'repeated capturing group' since it omits '?:' – Alvin K. May 02 '14 at 08:00
  • @AlvinK., actually I posted my answer 3 hours ago and posted demo2 2 hours ago. He posted his answer 1 hour ago. – sshashank124 May 02 '14 at 08:16
  • sshashank124: Demo2 wont parse empty fields like "ax;;cyz;def;eghi;xyzw", but can be fixed by changing '+' to '*' though. – Alvin K. May 02 '14 at 16:48
2

For this specific string instance, you could also use the following.

[^.]*(?=(?:\.[^.]*){3}$)

Regular expression

[^.]*           any character except: '.' (0 or more times)
(?=             look ahead to see if there is:
 (?:            group, but do not capture (3 times):
 \.             '.'
  [^.]*         any character except: '.' (0 or more times)
){3}            end of grouping
 $              before an optional \n, and the end of the string
)               end of look-ahead

See Live demo

hwnd
  • 69,796
  • 4
  • 95
  • 132
  • If you change `{3}` to `{4}`, it matches 'bb'. Hence this is a ideal solution if the delimiters ';' are fixed since it is counting backwards. – Alvin K. May 02 '14 at 05:23
2

You can use the following regex and replace it with $1Hello$3. n-1 => 2.

^((?:[^;]*;){2})([^;]*)(.*)$

Regular expression visualization

Demo

Ulugbek Umirov
  • 12,719
  • 3
  • 23
  • 31