edaus
edaus

Reputation: 199

Regex expression to cut string at nth occurrence of character and return first part of string

I have found the answer for a case which returns the second part of the string, eg:

"qwe_fs_xczv_xcv_xcv_x".replace(/([^\_]*\_){**nth**}/, ''); - where is nth is the amount of occurrence to remove.

If nth=3, the above will return “xcv_xcv_x”

Details in this StackOverflow post: Cutting a string at nth occurrence of a character

How to change the above regular expression to return the first part instead (ie. “qwe_fs_xczv”)?

Upvotes: 4

Views: 1466

Answers (3)

Ori Drori
Ori Drori

Reputation: 191976

Use String.match() to look from the start (^) of the string, for three sequences of characters without underscore, that might start with an underscore (regex101):

const result = "qwe_fs_xczv_xcv_xcv_x".match(/^(?:_?[^_]+){3}/);
console.log(result);

Upvotes: 1

Pranav C Balan
Pranav C Balan

Reputation: 115222

You need to use end anchor($) to assert ending position.

"qwe_fs_xczv_xcv_xcv_x".replace(/(_[^_]*){nth}$/, ''); 
//            --------------------^-----------^--- here

console.log(
  "qwe_fs_xczv_xcv_xcv_x".replace(/(_[^_]*){3}$/, '')
)


UPDATE : In order to get the first n segments you need to use String#match method with slight variation in the regex.

"qwe_fs_xczv_xcv_xcv_x".match(/(?:(?:^|_)[^_]*){3}/)[0]

console.log(
  "qwe_fs_xczv_xcv_xcv_x".match(/(?:(?:^|_)[^_]*){3}/)[0]
)
In the above regex (?:^|_) helps to assert the start position or matching the leading _. Regex explanation here.


Another alternative for the regex would be, /^[^_]*(?:_[^_]*){n-1}/. Final regex would be like:

/^[^_]*(?:_[^_]*){2}/

console.log(
  "qwe_fs_xczv_xcv_xcv_x".match(/^[^_]*(?:_[^_]*){2}/)[0]
)

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370759

If you want to use replace, then capture up to right before the third _ and replace with that group:

const re = /^(([^_]*_){2}[^_]*(?=_)).*$/;
console.log("qwe_fs_xczv_xcv_xcv_x".replace(re, '$1'));
console.log("qwe_fs_xczv_xcv_xcv_x_x_x".replace(re, '$1'));

But it would be nicer to use match to match the desired substring directly:

const re = /^([^_]*_){2}[^_]*(?=_)/;
console.log("qwe_fs_xczv_xcv_xcv_x".match(re)[0])
console.log("qwe_fs_xczv_xcv_xcv_x_x_x".match(re)[0])

Upvotes: 1

Related Questions