2

In JavaScript I would like to replace all spaces that don't match the following Regex with percentages (%):

\b[a-zA-Z]\s\b

I try to exclude all the spaces that sit next to a single character and replace all the other. In case:

True that A B C School is great for kids and C D E School is not

all the spaces except these between A-B and B-C and C-S should be replaced with percentages. So the result is:

True%that%A B C School%is%great%for%kids%and%C D E School%is%not

I read:

  1. Regex negative match query
  2. Replace part of string that doesn't match regex

but it didn't give me the ultimate answer.

Currentlyquery.replace(\b[a-zA-Z]\s\b,'%') replaces exactly the spaces that should be left as they are.

Could you advise how to negate my expression in the correct way?

Greg Wozniak
  • 5,209
  • 3
  • 26
  • 29

5 Answers5

1

Match and capture the pattern you have, and just match any other whitespace in other contexts:

var s = "True that A B C School is great for kids and C D E School is not";
var rx = /\b([a-zA-Z]\s)\b|\s/g;
console.log(
  s.replace(rx, function($0,$1) { return $1 ? $1 : "%"; })
  // ES6+ syntax
  // s.replace(rx, ($0,$1) => $1 ? $1 : "%" )
);
// => True%that%A B C School%is%great%for%kids%and%C D E School%is%not

Details

  • \b([a-zA-Z]\s)\b - a word boundary, then any ASCII letter and a whitespace (captured into Group 1) followed with a word boundary
  • | - or
  • \s - 1 whitespace char

Inside the anonymous method (or arrow method), $0 stands for the whole match and $1 stands for the captured text (Group 1 value). If Group 1 matched, we just return its value (so, the whitespaces after 1 letter words are kept). Else, the whitespace matched is replaced with %.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

There is no need to negate any expression, you could just match "Two or more characters followed by a space"

Replace

([a-zA-Z]{2,})\s

By

$1
Leethium
  • 1
  • 1
  • 1
    So, you think OP does not want to replace whitespace after digits? Or at the start/end of the string, etc.? – Wiktor Stribiżew Jun 11 '18 at 09:16
  • This could work but it's 86 steps and 10 matches while mine with \b seems to be a bit faster. However, could be in use if nothing else comes up as I see it does the job too. – Greg Wozniak Jun 11 '18 at 09:23
0

Try

console.log("[foo bar foobar   barfoo b f f b ]".replace(/([a-z]{2,})(\s+)/gi, "$1#"));
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • Does not match spaces at the start of the string or after non-alphabetic characters. – MT0 Jun 11 '18 at 09:20
0

Check this out. hope it helps. what it does is it first find the match needed at least 2 letters before a space, then it replaces it with a pipe'|'. just change it to whatever you want. you can use this as your base and expand from here if you have more conditions to add

var myString = 'A B C School is great for kids';
    
var result = myString.replace(/\w{2}\s/gi, match => match.replace(' ', '|'))

document.writeln(result)
Semi-Friends
  • 480
  • 5
  • 17
  • Does not match spaces at the start of the string or after non-word characters. I.e. `Insert Names' School is great for kids`. Also, why use a function with another replace rather than a capturing group and use `$1` in the replacement string? – MT0 Jun 11 '18 at 09:42
  • `you can use this as your base and expand from here if you have more conditions to add` - space at the start of the string? shouldn't that be done by just trimming? as per other char. well, if you look at what the user has provided, you would've had an idea why i use `\w`. – Semi-Friends Jun 14 '18 at 09:31
  • btw. please give an example using this idea of yours ` a capturing group and use $1 in the replacement string`. would've been great to learn something from you :) – Semi-Friends Jun 14 '18 at 09:33
  • 1
    `myString.replace(/(\w{2})\s/gi, '$1|')` is what I meant with a capturing group to simplify your code. However, it still does not address any of the other issues I've raised with the answer. – MT0 Jun 14 '18 at 10:16
  • woahhh... i don't know this. thanks for sharing. will read the documentation again – Semi-Friends Jun 19 '18 at 09:48
0

You can match either:

  • a non-word boundary \B followed by a non-whitespace character \S; or
  • the start of the string ^

Followed by one-or-more whitespace characters \s+ using the regular expression:

/(\B\S|^)\s+/g

For example:

var regex = /(\B\S|^)\s+/g;

var tests = [
  " ",
  " A B C Test DE",
  "True that A B C School is great for kids and C D E School is not"
];

for ( var i = 0; i < tests.length; i++ )
{
  console.log( `"${tests[i]}" -> "${tests[i].replace( regex, '$1%' )}"` );
}
MT0
  • 143,790
  • 11
  • 59
  • 117