For PCRE / Perl / Ruby / Java / .net
find:
(?:\G(?!^)|(?<!\S)(?!Joker(?!\S)))\S
replace:
$
demo
more details:
(?: \G (?!^)
If your words consist only of the characters of the word, you can simplify the pattern playing with and without words: (?:\G\B|\b(?!Joker\b))\w
Another way (PCRE / Perl): without the \G function and using the backtracking verb (*SKIP) (fewer steps are required):
\s*(?:Joker(?:\s+|$))*(*SKIP)\K.
Sharpness (*SKIP) is only useful when the line ends with a forbidden word or space. You can also replace it with (*COMMIT) .
demo
or
\bJoker\b(*SKIP)(*F)|\S
and with the regex pypi python module (which has a word boundary for the beginning and one for the end of the word):
\mJoker\M(*SKIP)(*F)|\S
One that works with Javascript (if there is something just for replacement):
find:
((?:\s+|\bJoker\b)*)\S((?:\s+Joker)*\s*$)?
replace: (backreference to group1, escaped $, backreference to group2)
$1$$$2
demonstration
Another version of Javascript that uses the y flag (which makes matches match), but unfortunately this one is not supported by Internet Explorer, Safari, and mobile browsers other than Firefox mobile:
var strs = ['Horse Banana Joker RoXx0r A_Long_Word Joker 1337 Joke Poker Joker', 'Joker Joker Joker']; strs.forEach(function (s) { console.log(s.replace(/(?=((?:\s+|\bJoker\b)*))\1./gy, '$1$$')); });
(?=(...))\1 emulates an atomic group (which prohibits backtracking).
Casimir et Hippolyte
source share