Reputation: 199
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
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
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]
)
(?:^|_)
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
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