Javascript print some characters after regex match - javascript

Input string is "F000668A - EED14F50 - 000EED1KFF0000000F03".
I want to print/save 4 characters after EED1. The number of EED1 can 1 or more.
In the above example, the expected result is => 4F50,KFF0.
My code:
var input = "F000668A - EED14F50 - 000EED1kFF0000000F03"
const string = input.toLowerCase().replace(/\s/g, '').replace(/(\r\n|\n|\r)/gm, ""); //Lowercase it, delete spaces and linebreaks.
string.match(/eed1/g).forEach((element) => {
console.log(element)
});
Result:
eed1
eed1
But when I try to print further characters then the script print only 1 item.
string.match(/eed1(.*)/g)
Result:
eed14f50-000eed1kff0000000f03
How can I get the requested info with regex? (or an other way)
Thank you in advance.

You can use
const input = "F000668A - EED14F50 - 000EED1kFF0000000F03";
const matches = input.replace(/\s/g, '').matchAll(/eed1([a-z0-9]{4})/ig);
console.log(Array.from(matches, m => m[1]));
Note:
You do not need to replace line breaks separately from other whitespaces, \s matches \n, \r, and the rest of vertical whitesapce
There is no need to lowercase the input, you can use /i flag to match in a case insensitive way
/eed1([a-z0-9]{4})/ig will match all occurrences of eed1 (case insensitively) and then capture four letters/digits, and matchAll will ensure the access to all the capturing group values (match() discarded them all as the regex was built with the g flag).
See the regex demo.

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 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);

How to remove invalid characters from a hyphenated serial key while preserving the single hyphen separator rule?

I want to remove letters from (a1-800-b-400), but naively doing so results in (1-800--400).
How do I get (1-800-400)?
If it involves RegExp, please explain how it works.
This is the RegExp you need:
/[^\d\()-]/g
/ / are simply indicators that you're writing a RegExp literal.
The trailing g flag means find all matches, instead of just one.
Everything between the [ ] are the characters you want to match.
But the ^ symbol means the opposite; don't match.
\d means Number, \( means open parenthesis (escaped), ) is obvious, as is -.
const regExpA = /[^\d\()-]/g;
const regExpB = /--/g;
const string = '(a1-800-b-400)';
const result = string
.replace(regExpA, '') // (1-800--400)
.replace(regExpB, '-'); // (1-800-400)
console.log(result);

Regex to detect dates separated by newlines

I'm trying to validate text that's in the format of dates separated by newlines.
The date format needs to be in the form of MM-DD-YYYY.
So a sample could be
MM-DD-YYYY\n
MM-DD-YYYY\n
MM-DD-YYYY
Where there could be an infinite amount of dates entered that are separated by newlines
I've tried /^(\d{2})-(\d{2})-(\d{4})\s+$/ but that doesn't seem to fully work.
Note: I want this to allow for any leading, trailing whitespace and empty newlines as well.
Basically,
A space character
A carriage return character
A newline character
I'm not partial to using regexes. If another way is simpler, desired, more efficient, than I'd gladly switch to that. Thanks!
To validate a string with multiple date-like strings in it with or without leading/trailing whitespace, allowing empty/blank lines, you may use
A method to split the text into lines and use .every() to test each line against a simple pattern:
text.split("\n").every(x => /^\s*(?:\d{2}-\d{2}-\d{4}\s*)?$/.test(x))
NOTE: This will validate a blank input!
Details
^ - start of string
\s* - 0+ whitespaces
(?: - starts a non-capturing group
\d{2}-\d{2}-\d{4} - two digits, -, two digits, - and four digits
\s* - 0+ whitespaces
)? - end of the group, repeat 1 or 0 times (it is optional)
$ - end of string.
A single regex for the multiline string
/^\s*\d{2}-\d{2}-\d{4}(?:[^\S\n]*\n\s*\d{2}-\d{2}-\d{4})*\s*$/.test(text)
See the regex demo. This will not validate blank input.
This regex is long, but is still efficient since the backtracking is minimal (see [^\S\n]*\n\s* part where the first [^\S\n]* matches any whitespace but a line feed, then \n matches a newline (hence, no backtracking here) and then \s* matches 0+ whitespace (again, \n is not quantified so no backtracking into the pattern is \s* fails). The (?:[^\S\n]*\n\s*\d{2}-\d{2}-\d{4})* part is a * quantified non-capturing group that matches 0 or more occurrences of the quantified pattern sequence.
JS demos:
var matching_text = "\n01-01-2020\n 01-01-2020\n01-01-2020 \n\n\n 01-01-2020 \n";
var non_matching_text = "\n01-01-2020\n 01-01-2020\n01-01-2020 \n\n\n 01-01-2020 \n01201-01-20202020";
var regex_1 = /^\s*(?:\d{2}-\d{2}-\d{4}\s*)?$/;
var regex_2 = /^\s*\d{2}-\d{2}-\d{4}(?:[^\S\n]*\n\s*\d{2}-\d{2}-\d{4})*\s*$/;
// Test Solution 1:
console.log(matching_text.split("\n").every(x => regex_1.test(x))); // => true
console.log(non_matching_text.split("\n").every(x => regex_1.test(x))); // => false
// Test Solution 2:
console.log(regex_2.test(matching_text)); // => true
console.log(regex_2.test(non_matching_text)); // => false
You can use something like below to get all matches that satisfy the regular expression. Notice the parentheses () are only around the date part (\d{2}-\d{2}-\d{4}) so that is what you will end up capturing. Since the global flag g is also set on the regex, this will return all occurrences of the parenthesized expression.
Edit: added support for a leading and trailing whitespace.
Edit 2: added ^ and $ so the regex doesn't allow for more than 2 digits in day and more than 4 digits in year.
Run and test:
let regex = /[\\s]*(\d{2}-\d{2}-\d{4})[\\s]*[\\n]*/g;
let dates = " 12-02-2020 \n 09-10-2020\n 03-03-2020 ";
console.log( dates.match(regex) );
EDIT: In order to validate the string of dates you could use the regex.test() method like this:
let regex = /^\s*\d{2}-\d{2}-\d{4}\s*$/;
let dateString = " 12-02-2020 \n 09-10-2020\n 03-03-2020 ";
var dates = dateString.split('\n');
var datesValid = () => {
dates.forEach((el) => {
if(!regex.test(el))
return false;
});
return true;
};
console.log( datesValid() );

Javascript - Regex - how to filter characters that are not part of regex

I want to accept words and some special characters, so if my regex
does not fully match, let's say I display an error,
var re = /^[[:alnum:]\-_.&\s]+$/;
var string = 'this contains invalid chars like ##';
var valid = string.test(re);
but now I want to "filter" a phrase removing all characters not matching the regex ?
usualy one use replace, but how to list all characters not matching the regex ?
var validString = string.filter(re); // something similar to this
how do I do this ?
regards
Wiktor Stribiżew solution works fine :
regex=/[^a-zA-Z\-_.&\s]+/g;
let s='some bloody-test #rfdsfds';
s = s.replace(/[^\w\s.&-]+/g, '');
console.log(s);
Rajesh solution :
regex=/^[a-zA-Z\-_.&\s]+$/;
let s='some -test #rfdsfds';
s=s.split(' ').filter(x=> regex.test(x));
console.log(s);
JS regex engine does not support POSIX character classes like [:alnum:]. You may use [A-Za-z0-9] instead, but only to match ASCII letters and digits.
Your current regex matches the whole string that contains allowed chars, and it cannot be used to return the chars that are not matched with [^a-zA-Z0-9_.&\s-].
You may remove the unwanted chars with
var s = 'this contains invalid chars like ##';
var res = s.replace(/[^\w\s.&-]+/g, '');
var notallowedchars = s.match(/[^\w\s.&-]+/g);
console.log(res);
console.log(notallowedchars);
The /[^\w\s.&-]+/g pattern matches multiple occurrences (due to /g) of any one or more (due to +) chars other than word chars (digits, letters, _, matched with \w), whitespace (\s), ., & and -.
To match all characters that is not alphanumeric, or one of -_.& move ^ inside group []
var str = 'asd.=!_#$%^&*()564';
console.log(
str.match(/[^a-z0-9\-_.&\s]/gi),
str.replace(/[^a-z0-9\-_.&\s]/gi, '')
);

Categories