tarponjargon
tarponjargon

Reputation: 1032

Javascript regex: match first 50 characters, respecting words

I'm trying to keep some nav bar lines short by matching the first 50 chars then concatenating '...', but using substr sometimes creates some awkward word chops. So I want to figure out a way to respect words.

I could write a function to do this, but I'm just seeing if there's an easier/cleaner way.

I've used this successfully in perl:

^(.{50,50}[^ ]*)

Nice and elegant! But it doesn't work in Javascript :(

let catName = "A string that is longer than 50 chars that I want to abbreviate";
let regex = /^(.{50,50}[^ ]*)/;
let match = regex.exec(catName);

match is undefined

Upvotes: 2

Views: 1973

Answers (4)

guest271314
guest271314

Reputation: 1

You can .split() \s, count characters at each array element which contains a word at for loop, when 50 or greater is reached when .length of each word is accrued at a variable, .slice() at current iteration from array, .join() with space characters " ", .concat() ellipses, break loop.

let catName = "A string that is longer than 50 chars that I want to abbreviate";

let [stop, res] = [50, ""];

if (catName.length > stop) {

  let arr = catName.split(/\s/);

  for (let i = 0, n = 0; i < arr.length; i++) {
    n += arr[i].length;
    if (n >= stop) {
      res = arr.slice(0, i).join(" ").concat("...");
      break;
    };
  }

} else {
  res = catName.slice(0, 50).concat("...")
}

document.querySelector("pre").textContent = res;
<pre></pre>

Upvotes: 0

VisioN
VisioN

Reputation: 145438

Probably the most fool-proof solution with regular expression would be to use replace method instead. It won't fail with strings less than 50 characters:

str.replace(/^(.{50}[^ ]*).*/, '$1...');

var str = 'A string that is longer than 50 chars that I want to abbreviate';
console.log( str.replace(/^(.{50}[^ ]*).*/, '$1...') );

Upvotes: 1

tarponjargon
tarponjargon

Reputation: 1032

Tinkering with Pranov's answer, I think this works and is most succinct:

// abbreviate strings longer than 50 char, respecting words
if (catName.length > 50) {  
    catName = catName.match(/^(.{50,50}[^ ]*)/)[0] + '...';
}

The regex in my OP did work, but it was used in a loop and was choking on strings that already had fewer than 50 chars.

Upvotes: 0

Pranav C Balan
Pranav C Balan

Reputation: 115242

Use String#match method with regex with word boundary to include the last word.

str.match(/^.{1,50}.*?\b/)[0]

var str="I'm trying to keep some nav bar lines short by matching the first 50 chars then concatenating '...', but using substr sometimes creates some awkward word chops. So I want to figure out a way to respect words.";

console.log('With your code:', str.substr(0,50));
console.log('Using match:',str.match(/^.{1,50}.*?\b/)[0]);

Upvotes: 3

Related Questions