i need to truncate portions of a string that are found between a regex pattern.
- if a portion length is
<=
to the given padding, leave the portion as it is. - the starting portion should be truncated from the left.
- the ending portion should be truncated from the right.
- the portions in between should be truncated in the middle.
code:
// note that the 'x' characters below could be any characters, even spaces.
const str = 'xxxxx<mark>foo</mark>xx<mark>bar</mark>xxxxxxxxx<mark>baz</mark>xxxxxxxx'
const truncateBetweenPattern = (str, pattern, padding=0, sep='...') => {
// code
}
const pattern = '(<mark>. </mark>)' // (not sure if this is valid)
const result = truncateBetweenPattern(str, pattern, 3)
output:
result === '...xxx<mark>foo</mark>xx<mark>bar</mark>xxx...xxx<mark>baz</mark>xxx...'
CodePudding user response:
The following code should do what you want:
const truncateBetweenPattern = (str, pattern, padding=0, sep='...') => {
const regex = new RegExp(pattern, 'g');
let result = '';
let match;
while ((match = regex.exec(str)) !== null) {
// Truncate the left portion of the match if needed.
const left = match.index;
if (left > padding) {
result = str.slice(0, left - padding) sep;
} else {
result = str.slice(0, left);
}
// Truncate the middle portion of the match if needed.
const middle = match[0].length;
if (middle > padding * 2) {
result = str.slice(left, left padding) sep str.slice(left middle - padding);
} else {
result = match[0];
}
// Truncate the right portion of the match if needed.
const right = str.length - regex.lastIndex;
if (right > padding) {
result = sep str.slice(regex.lastIndex, regex.lastIndex padding);
} else {
result = str.slice(regex.lastIndex);
}
// Update the string for the next iteration.
str = str.slice(regex.lastIndex);
}
return result;
}
Here's an example of how to use the function:
const str = 'xxxxx<mark>foo</mark>xx<mark>bar</mark>xxxxxxxxx<mark>baz</mark>xxxxxxxx';
const pattern = '(<mark>. </mark>)';
const result = truncateBetweenPattern(str, pattern, 3);
console.log(result);
This should output:
xxx<mark>foo</mark>x...<mark>ba...z</mark>...
CodePudding user response:
Here is a solution using regular expressions and the String.prototype.replace method:
const truncateBetweenPattern = (str, pattern, padding = 0, sep = '...') => {
// Use a regular expression to find all matches of the pattern in the string
const matches = str.match(new RegExp(pattern, 'g'));
// Iterate over the matches and create a replacement string for each match
const replacements = matches.map((match) => {
// Check the length of the match
if (match.length <= padding * 2) {
// If the length is <= padding * 2, return the original match
return match;
}
// Otherwise, return a truncated version of the match
return match.substring(0, padding) sep match.substring(match.length - padding);
});
// Replace the matches in the original string with the truncated versions
return str.replace(new RegExp(pattern, 'g'), () => replacements.shift());
};
Here's an example of how you could use this function:
const str = 'xxxxx<mark>foo</mark>xx<mark>bar</mark>xxxxxxxxx<mark>baz</mark>xxxxxxxx';
const pattern = '(<mark>. </mark>)'; // (not sure if this is valid)
const result = truncateBetweenPattern(str, pattern, 3);
console.log(result); // '...xxx<mark>foo</mark>xx<mark>bar</mark>xxx...xxx<mark>baz</mark>xxx...'