White list in str.replace - javascript

i'm using this code to replace everyone who has website link in they name change it to nothing e.g
Username - Somewebsite.com -> Username -
For that I use this code:
name.replace(/([a-zA-Z0-9\-]*\.com)/g, '');
But I want to make it so when user is using my website adress in their name to not remove it e.g
Username - Mywebsitename.com -> Username - Mywebsitename.com

Easiest would be to just use a callback for replace() and weed out matches on a certain string
var mySite = 'Somewebsite.com';
var name = "Username - Somewebsite.com";
var result = name.replace(/([a-zA-Z0-9\-]*\.com)/g, function(what) {
return what === mySite ? what : "";
});
FIDDLE

Nearly pure regex solution:
/\s+\-\s+(?!Mywebsite\.com)([a-zA-Z0-9\-]+)\.com/i
Working example:
var regex = /\s+\-\s+(?!Mywebsite\.com)[a-zA-Z0-9\-]+\.com/i
var string = 'Username - Somewebsite.com'
var output = 'Username -'
console.log('Match:', string)
console.log('Result:', string.replace(regex, ' -'))
console.log('Correct:', (string.replace(regex, ' -') === output) === true)
console.log('') // new line
var string = 'Username - Mywebsite.com'
var output = 'Username - Mywebsite.com'
console.log('Match:', string)
console.log('Result:', string.replace(regex, ' -'))
console.log('Correct:', (string.replace(regex, ' -') === output) === true)
Regex Explanation:
/ //-> open regex
\s+ //-> match one or more spaces
\- //-> match one literal dash
\s+ //-> match one or more spaces
(?!Mywebsite\.com) //-> look ahead & assert next match is not "Mywebsite.com"
([a-zA-Z0-9\-]+) //-> match one or more lower or upper case letter, digits, & dot
\. //-> match literal dot
c //-> match c
o //-> match o
m //-> match m
/ //-> close regex
i //-> make search case insensitive
Look behind would likely have been more ideal for this, but it's not supported in JavaScript.
I hope that helps!

Related

Get Initials of full names with accented characters through REGEX

I want to get the initials of a full name even if the name has accents or dots or comma.
If I have the name:
"Raúl, Moreno. Rodríguez Carlos"
I get "RLMRGC".
my code is:
user.displayName.match(/\b[a-zA-Z]/gm).join('').toUpperCase()
I want to get "RMRC". Thanks in advance.
My guess is that this expression might work:
const regex = /[^A-Z]/gm;
const str = `Raúl, Moreno. Rodríguez Carlos`;
const subst = ``;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log(result);
Try this (with REGEX):
const data = "Raúl, Moreno. Rodríguez Carlos";
const result = data.match(/\b[A-Z]/gm);
console.log(result);
other solution without REGEX:
const data = "Ędward Ącki";
const result = [...data].filter((c, k, arr) => c !== ' ' && (k == 0 || arr[k-1] == ' ' ))
console.log(result);
A fully Unicode compatible solution should match any letter after a char other than letter or digit.
Here are two solutions: 1) an XRegExp based solution for any browser, and 2) an ECMAScript 2018 only JS environment compatible solution.
var regex = XRegExp("(?:^|[^\\pL\\pN])(\\pL)");
console.log( XRegExp.match("Łukasz Żak", regex, "all").map(function(x) {return x.charAt(x.length - 1);}).join('').toUpperCase() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>
ECMAScript 2018 compliant solution:
// ONLY WORKING IN ECMAScript2018 COMPLIANT JS ENVIRONMENT!
var regex = /(?<![\p{N}\p{L}])\p{L}/gu;
console.log( "Łukasz Żak".match(regex).join('').toUpperCase() );
// => ŁŻ
NOTE:
(?:^|[^\pL\\pN])(\pL) matches start of a string and any char but letter and digit and then matches any letter (since the char matched by the first non-capturing group is not necessary, .map(function(x) {return x.charAt(x.length - 1);}) is required to get the last char of the match)
(?<![\p{N}\p{L}])\p{L} matches any letter (\p{L}) that is not preceded with a digit or letter (see the negative lookbehind (?<![\p{N}\p{L}]))

regex validation from a to z with an exception of certain characters

I have a variable like this
var time = "12h 55m";
I am only allowed to use H,h,M,m characters in the string. If i have something like this
var time = "12hk 55m";
then it should produce an error. how can I validate this using regex expression.'
looking for something like this
if (stringToTest.match(/^[a-zA-Z0-9]*$/))
Try
/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i
It matches 2 digits followed by either h or m, followed by one or more space, followed by 2 digits followed by either h or m
Following will match
"12h 55m".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)
"12m 55h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)
"2m 55h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)
"12m 5h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)
These will not
"122h 555m".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)
The reg in regex stands for regular and your data seems to have a possibility to be irregular. I'd recommend to do the check differently but since you're looking for a regex solution:
/^(\d{2,3}h\s+\d{1,2}m)|(\d{1,2}m\s+\d{2,3}h)$/gi
This will match h and m in either order but will reject if either is in the string twice.
You could use following regex ^\d{1,2}[hmHM]\s\d{1,2}[hmHM]:
^ asserts position at start of the string
\d matches a digit (equal to [0-9])
{1,2} Quantifier — Matches between 1 and 2 times, as many times as possible, giving back as needed
[hmHM] matches a single character in the list hmHM (case sensitive)
\s matches any whitespace character
\d{1,2}[hmHM] as described above
\g modifier: global. All matches (don't return after first match)
See following snippet to test it:
var regex = /^\d{1,2}[hmHM]\s\d{1,2}[hmHM]/g;
function check(par){
console.log(par.value + " match: " + regex.test(par.value));
}
Insert a text in the input <input type="text" id="test" value="" onchange="javascript:check(this)">
The accepted answer apparently satisfies the OP. But I noticed that in this comment the OP says that the character symbols should not be repeated. For example, 12h 12h should be invalid but all answers match this. I don't think this can be done using only regex. So here is an alternative solution:
function timeParser(timeStr) {
var acChars = ['h', 'H', 'm', 'M'];
if ((timeStr.match(/\s/g) || []).length !== 1) return false;
var tokens = timeStr.split(' ');
for (var token of tokens) {
var rx = new RegExp("\\d{1,3}[" + acChars.join("") + "]", "g");
if (!token.match(rx) ||
token.match(rx).length !== 1 ||
token !== token.match(rx)[0]) return false;
var tc = token.charAt(token.length - 1);
acChars.splice(acChars.indexOf(tc), 1);
}
return true;
}
var timearr = ["12h 12h", "1m1h 515M", "12hk 55m", "H 12m", "m 12H", "12H 11m", "00m 001h", "20M 1"];
for (var tim of timearr)
console.log(timeParser(tim));
and 12h 12h is not matched.

Javascript Regex to split line of log with key value pairs

I have a log like
t=2016-08-03T18:47:26+0000 lvl=dbug msg="Event Received" Service=SomeService
and I want to turn it into a javascript object like
{
t: 2016-08-03T18:47:26+0000,
lvl: dbug
msg: "Event Received"
Service: SomeService
}
But I am having trouble coming up with a regex that will detect the string "Event Received" in the log line.
I want to split the log line by space but because of the string it is much more difficult.
I am trying to come up with a regex that will detect the fields and parameters so that I can isolate them and split with the equal sign.
I suggest a regex without any lookahead:
var re = /(\w+)=(?:"([^"]*)"|(\S*))/g;
See the regex demo
The point is that the first group ((\w+)) captures the attribute name and the 2nd and 3rd are placed into a non-capturing "container" as alternative branches. Their values can be checked and then either one will be used to fill out the object.
Pattern details:
(\w+) - Group 1 (attribute name) matching 1+ word chars (from [a-zA-Z0-9_] ranges)
= - an equal sign
(?:"([^"]*)"|(\S*)) - a non-capturing "container" group matching either of the two alternatives:
"([^"]*)" - a quote, then Group 2 capturing 0+ chars other than ", and a quote
| - or
(\S*) - Group 3 capturing 0+ non-whitespace symbols.
var rx = /(\w+)=(?:"([^"]*)"|(\S*))/g;
var s = "t=2016-08-03T18:47:26+0000 lvl=dbug msg=\"Event Received\" Service=SomeService";
var obj = {};
while((m=rx.exec(s))!==null) {
if (m[2]) {
obj[m[1]] = m[2];
} else {
obj[m[1]] = m[3];
}
}
console.log(obj);
You can use this regex to capture various name=value pairs:
/(\w+)=(.*?)(?= \w+=|$)/gm
RegEx Demo
Code:
var re = /(\w+)=(.*?)(?= \w+=|$)/gm;
var str = 't=2016-08-03T18:47:26+0000 lvl=dbug msg="Event Received" Service=SomeService';
var m;
var result = {};
while ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex)
re.lastIndex++;
result[m[1]] = m[2];
}
console.log(result);
Use this pattern:
/^t=([^ ]+) lvl=([^ ]+) msg=(.*?[a-z]") Service=(.*)$/gm
Online Demo
To achieve expected result, use below
var x = 't=2016-08-03T18:47:26+0000 lvl=dbug msg="Event Received" Service=SomeService';
var y = x.replace(/=/g,':').split(' ');
var z = '{'+ y+'}';
console.log(z);
http://codepen.io/nagasai/pen/oLPRAy

Regex for Accepting any number of Characters and -

Can any one give me correct Regular Expression to accept Name starting with characters and ending with characters, in middle i can allow -
Ex: ABC or ABC-DEF or ABC-DEF-GHI
But it should not start or end with -
Ex: -ABC or -ABC- or ABC-
Here is my Regular Expression:
var regex = /^[A-Za-z]-?[A-Za-z]*-?([A-Za-z]+)+$/
This works perfactly fine for me, but if suppose i want to give name as AB-CD-EF-GH than this don't work.
Note: Remember that Name should start with Characters and End with Characters and in between i can have - but not -- twice. It has to be associated with characters like a-b-c-d
^[A-Za-z]+(?:-[A-Za-z]+)*$
This simple regex will do it for you.See demo.
https://regex101.com/r/sJ9gM7/55
var re = /^[A-Za-z]+(?:-[A-Za-z]+)*$/gim;
var str = 'ABC\nABC-DEF\n-ABC\nABC-\nAB-CD-EF-GH\n';
var m;
if ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
I believe this is what you want :
/^[A-Z](-[A-Z]+)*[A-Z]$/i
Analysis :
/^ Start of string
[A-Z] Any alphabetic character
( Group
- A hyphen character
[A-Z]+ One or more alphabetic characters
)* 0 or more repititons of group
[A-Z] Any alphabetic character
$/i End of string, allow upper or lower case alpha
You can use .* inside to allow any number of any characters except for a newline:
var regex = /^(?!.*--.*$)[A-Za-z].*[A-Za-z]$/
(?!.*--.*$) will make sure double hyphens are not allowed.
Please check the regex demo here.
function ValIt(str)
{
var re = /^(?!.*?--.*?$)[A-Za-z].*[A-Za-z]$/g;
if ((m = re.exec(str)) !== null)
return true;
else
return false;
}
document.getElementById("res").innerHTML = 'RTT--rrtr: ' + ValIt('RTT--rrtr') + "<br>ER#$-wrwr: "+ ValIt('ER#$-wrwr') + "<br>Rfff-ff-d: " + ValIt('Rfff-ff-d');
<div id=res />
var rgx = /^[A-Za-z]+(-[A-Za-z]+)*$/;
rgx.test("ABC"); // true
rgx.test("ABC-DEF"); // true
rgx.test("AB-CD-EF-GH"); // true
rgx.test("-AB-CD-EF-GH"); // false
rgx.test("AB-CD-"); // false
rgx.test("AB--CD"); // false

Regex that allows only one space in the first/last name validation

I'm trying to write a regular expression to remove white spaces from just the beginning of the word, not after, and only a single space after the word.
Used RegExp:
var re = new RegExp(/^([a-zA-Z0-9]+\s?)*$/);
Test Exapmle:
1) test[space]ing - Should be allowed
2) testing - Should be allowed
3) [space]testing - Should be allowed but have to trim the space at the first
4) testing[space] - Should be allowed but have to trim the space at the last
5) testing[space][space] - should be allowed but have to trim the space at the last
6) test[space][space]ing - one space should be allowed but the remaining spaces have to be trimmed.
Any idea how this can be achieved using regex?
EDIT:
I have this,
var regExp = /^(\w+\s?)*\s*$/;
if(regExp.test($('#FirstName').val())){
$('#FirstName').val().replace(/\s+$/, '');
}else{
var elm = $('#FirstName'),
msg = 'First Name must consist of letters with no spaces';
return false;
}
Using capturing group:
var re = /^\s+|\s+$|(\s)\s+/g;
'test ing'.replace(re, '$1') // => 'test ing'
'testing'.replace(re, '$1') // => 'testing'
' testing'.replace(re, '$1') // => 'testing'
'testing '.replace(re, '$1') // => 'testing'
'testing '.replace(re, '$1') // => 'testing'
'test ing'.replace(re, '$1') // => 'test ing'
I'd probably be lazy to keep it simple and use two separate REs:
// Collapse any multiple spaces into one - handles cases 5 & 6
str.replace(/ {2,}/, ' ');
// Trim any leading space
str.replace(/^ /, '');
Or, as one statement:
var result = str.replace(/ {2,}/, ' ').replace(/^ ?/, '');
How about this:
replace(/^ | $|( ) +/, $1)?

Categories

Resources