How to format a JavaScript string with replaceAll using regex - javascript

I am trying to format a kind of a board game notation which consists of tabs and spaces.
The original string is looking like this:
1. \td11-d9 \te7-e10 \n2. \ta8-c8 \tg7-g10xf10 \n3. \th11-h9 \tf7-i7
I used this replace method to clean up all of the tabs and new lines
string.replace(/\s\s+/g, ' ').replaceAll('. ', '.');
So, after that the string is looking like this:
1.d11-d9 e7-e10 2.a8-c8 g7-g10xf10 3.h11-h9 f7-i7
However, I want to add more space before the number with the dot. So, the string must look like this with 3 spaces before the number of the move (the number with the dot):
1.d11-d9 e7-e10 2.a8-c8 g7-g10xf10 3.h11-h9 f7-i7
Can I also make all of these operations with a one line code or just one JavaScript method?

Here is how you can do this in a single .replace call:
const s = "1. \td11-d9 \te7-e10 \n2. \ta8-c8 \tg7-g10xf10 \n3. \th11-h9 \tf7-i7 ";
var r = s.replace(/([.\s])\s*\t|\s+$|\n(?=\d\.)/g, '$1');
console.log(r);
//=> "1.d11-d9 e7-e10 2.a8-c8 g7-g10xf10 3.h11-h9 f7-i7"
RegEx Breakup:
([.\s])\s*\t: Match dot or a whitespace and capture in group #1 followed by 0+ whitespaces followed by a tab. We will put back this replacement using $1
|: OR
\s+$: Match 1+ whitespaces before end
|: OR
\n(?=\d\.): Match \n if it is followed by a digit and a dot

You can use lookahead with (?=[1-9]) and (?=[a-z]) to check if the number add two spaces, and if a letter just add one space.
const string = `1. \td11-d9 \te7-e10 \n2. \ta8-c8 \tg7-g10xf10 \n3. \th11-h9 \tf7-i7`
const result = string.replace(/\s+(?=[a-z])/gi, ' ').replace(/\s+(?=[1-9])/gi, ' ').replaceAll('. ', '.');
console.log(result)

Related

Extract text between last slash and last dot using regex

I have string like this in javascript
at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/logger.service.ts:107:29)
I want to extract logger.service from it. the formula is between last / to last .
I can extract from last / using /([^\/]+$)/g but don't know how to limit the finding to last .
Note: these are other examples:
at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/logger.ts:107:29)
expected: logger
at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/logger.js:107:29)
expected: logger
at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/api.logger.service.ts:107:29)
expected: api.logger.service
You can use
/.*\/(.*)\./
Details:
.* - any zero or more chars other than line break chars as many as possible
\/ - a / char
(.*) - Group 1: any zero or more chars other than line break chars as many as possible
\. - a . char.
See the JavaScript demo:
const text = "at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/api.logger.service.ts:107:29)";
const match = text.match(/.*\/(.*)\./)
if (match) {
console.log(match[1]);
}
We can try using a regex replacement approach here:
var log = "at LoggerService.log (/Users/apps/api/webpack:/pcs-goc-api/pcs-libs/logger/src/api.logger.service.ts:107:29)";
var output = log.replace(/^.*\/|\.[^.]*$/g, "");
console.log(output);
The regex pattern here says to match:
^.*\/ all content from the start up to and including the LAST /
| OR
\.[^.]*$ all content from the LAST dot until the end
Then, we replace with empty string, leaving behind the string we want.
([^\/]+)[.][^:]+:\d+:\d+
Demo: https://regex101.com/r/FeLRmi/1
[.] => "." character
[^:] => Any character except ":"
[^:]+ => One or more [^:]
:\d+ => One or more digits after ":"
All the other regex statements are your own.

Regex to avoid specific content

I have a string like 23DGERA#SPK_20W L+R FA-2#1+342HSHC#CPU_8PIN INTEL_TEST!#1+2356GHMX#SSD_256G MICRON_CONTENT#2 + blablabla.
What I would like to do is to split up the string by +, yet in SPK section there is a L+R that would interrupt the process. Is there any REGEX that could achieve what I want?
In result should be:
23DGERA#SPK_20W L+R FA-2#1
342HSHC#CPU_8PIN INTEL_TEST!#2
2356GHMX#SSD_256G MICRON_CONTENT#2
and now what i always get:
23DGERA#SPK_20W L
R FA-2#1
342HSHC#CPU_8PIN INTEL_TEST!#2
2356GHMX#SSD_256G MICRON_CONTENT#2
I'm using Javascript .split('+') by now.
Any help will be appretiated.
You can use a matching regex solution:
text.match(/(?:L\+R|[^+])+/g)
See the regex demo. Details:
(?: - start of a non-capturing group:
L\+R - L+R string
| - or
[^+] - any char other than +
)+ - end of the group, one or more occurrences.
See the JavaScript demo:
var text = '23DGERA#SPK_20W L+R FA-2#1+342HSHC#CPU_8PIN INTEL_TEST!#1+2356GHMX#SSD_256G MICRON_CONTENT#2';
console.log(text.match(/(?:L\+R|[^+])+/g));
ECMAScript 2018+ compliant solution
In case you want to migrate to a more modern ECMAScript flavor, you can use
text.split(/\+(?<!L\+(?=R))/)
This will match a + that is not part of an L+R string.
const text = '23DGERA#SPK_20W L+R FA-2#1+342HSHC#CPU_8PIN INTEL_TEST!#1+2356GHMX#SSD_256G MICRON_CONTENT#2';
console.log(text.split(/\+(?<!L\+(?=R))/));
See the regex demo.
Instead of splitting on a + you could match the format in the example data.
First match a part containing a single #, and then match till the first occurrence of # followed by a digit.
Note that the second match will be 342HSHC#CPU_8PIN INTEL_TEST!#1 instead of 342HSHC#CPU_8PIN INTEL_TEST!#2
\w+#\w+ [^#]*#\d\b
The pattern matches:
\w+#\w+ Match 1+ word characters, # and at 1+ word characters
[^#]*# Match a space, optional chars other than #, then match #
\d\b Match a digit and a word boundary to prevent a partial match
Regex demo
const s = "23DGERA#SPK_20W L+R FA-2#1+342HSHC#CPU_8PIN INTEL_TEST!#1+2356GHMX#SSD_256G MICRON_CONTENT#2 + blablabla";
const regex = /\w+#\w+ [^#]*#\d\b/g;
console.log(s.match(regex));
The string looks like a list of parts each with a quantity e.g. #1. You can use that to identify the correct + characters to split on.
Using a look-behind containing #\d+ -> (?<=#\d+) followed by the character you want to match (escaped because + has a special meaning) gives:
(?<=#\d+)\+
Using this in code we also need specify the g modifier to match all instances instead of just the first one.
const str = '23DGERA#SPK_20W L+R FA-2#1+342HSHC#CPU_8PIN INTEL_TEST!#1+2356GHMX#SSD_256G MICRON_CONTENT#2'
const items = str.split(/(?<=#\d+)\+/g);
console.log(items);

Regex Capture Character and Replace with another

Trying to replace the special characters preceded by digits with dot.
const time = "17:34:12:p. m.";
const output = time.replace(/\d+(.)/g, '.');
// Expected Output "17.34.12.p. m."
console.log(output);
I had wrote the regex which will capture any character preceded by digit/s. The output is replacing the digit too with the replacement. Can someone please help me to figure out the issue?
You can use
const time = "17:34:12:p. m.";
const output = time.replace(/(\d)[\W_]/g, '$1.');
console.log(output);
The time.replace(/(\d)[\W_]/g, '$1.') code will match and capture a digit into Group 1 and match any non-word or underscore chars, and the $1. replacement will put the digit back and replace : with ..
If you want to "subtract" whitespace pattern from [\W_], use (?:[^\w\s]|_).
Consider checking more special character patterns in Check for special characters in string.
You should look for non word(\w) and non spaces (\s) characters and replace them with dot.
You should use some live simulator for regular expressions. For example regex101: https://regex101.com/r/xIStHH/1
const time = "17:34:12:p. m.";
const output = time.replace(/[^\w\s]/g, '.');
// Expected Output "17.34.12.p. m."
console.log(output);

Regex: match last and second-last character

I need to wrap the two last characters in a string in a separate <span>:
-1:23 // This is what I have
-1:<span>2</span><span>3</span> // This is what I want
The following matches the last character – but how can I make it match the second last as well?
str.replace(/(.$)/, "<span>$1</span>");
Thanks :)
You may use
.replace(/.(?=.?$)/g, "<span>$&</span>")
See the regex demo
If these must be digits, replace . with \d:
.replace(/\d(?=\d?$)/g, "<span>$&</span>")
The pattern matches
\d - a digit
(?=\d?$) - that is followed with an end of string or a digit and end of string.
The $& is a replacement backreference that references the whole match value from the string replacement pattern.
JS demo:
console.log("-1:23".replace(/.(?=.?$)/g, "<span>$&</span>"));
console.log("-1:23".replace(/\d(?=\d?$)/g, "<span>$&</span>"));
Now, to make it more dynamic, you may use a limiting (range/interval) quantifier:
function wrap_chars(text, num_chars) {
var reg = new RegExp(".(?=.{0," + (num_chars-1) + "}$)", "g");
return text.replace(reg, "<span>$&</span>");
}
console.log(wrap_chars("-1:23", 1)); // wrap one char at the end with span
console.log(wrap_chars("-1:23", 2)); // wrap two chars at the end with span
You can add another group before the last one, which also matches a single character ((.)), then wrap each of them using references ($1 and $2):
var str = '-1:23'.replace(/(.)(.)$/, '<span>$1</span><span>$2</span>')
console.log(str);

How to remove everything up until the first character in Javascript?

I'm getting a string which returns an integer first, followed by a series of spaces and then the string I want. My goal is to just get "Moonwalking with Einstein" in this example. I'm using Javascript. What's the best way to achieve this?
2
Moonwalking with Einstein
You can use a str replace with a regex like this:
^[^A-Za-z]+
or
/^[^a-z]+/i
Working demo
var str = ' 2 \n\n\n\n\n\n\n\n Moonwalking with Einstein';
var result = str.replace(/^[^A-Za-z]+/, '');
The idea is to match whatever starts with a character that is not A-Z and a-z and replace it with an empty string and to keep what you want.
You can use JavaScript's replace function for this.
It looks like you are looking to replace digits and instances of two or more consecutive spaces
\d - Matches any digit
| - Or conditional symbol
\s - Matches any whitespace character
{2,} - Matches two or more
/g - Matches all instances
var string = " 2 Moonwalking with Einstein"
string = string.replace(/\d|\s{2,}/g, '')
var result = document.getElementById("result");
result.innerHTML = string;
<p id="result"></p>

Categories