I was going through a piece of code and I hit against this syntax
str.replace(re,function(raw, p1, p2, p3){
if (!/\/\//.test(p1)) { // <---- this one
//some more code
}
});
I understand that the test method matches one string with another, and checks if it is present. But what does this regex /\/\// matching the string to?
I checked the regex, and
\/ matches the character / literally
\/ matches the character / literally
so what does if(!//.test(p1)) doing?
The conditional is true if the string does not contain two consecutive slashes.
If first captured group () p1 contains // return false at if condition by converting true to false using ! operator
\/ matches the character / literally. The above regex will execute if condition if there are no 2 consecutive /.
check out this: here
Related
I have the string:
"Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25."
How to detached get results like:
["Vl.55.16b25", 3d.42.b50.59b30.90.24b35, 3d.56.67b70, ...]
The logic:
Condition 1: The End will be start b and 2 number. Example: b20, b25.
If pass condition 1 I need to check condition 2.
Condition 2: maybe like "3d" or 2 characters. If don't match condition 2 we need to pass the next character to the current block.
Many thanks.
If I understand your question correctly, the following code should work:
var string = "Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25.";
console.log(string.split(/(?<=b\d\d)\.(?=3d)/g))
Explanation:
(?<=) is look-behind.
b matches the literal character "b".
\d matches any digit so \d\d will match two digits in a row.
\. matches a literal ".", it needs the \ before it because otherwise it would match any character.
(?=) is look-ahead.
The g flag stands for global so the string will be split up at every occurrence of the regular expression.
This means that the string will be split at every occurrence of "." that is preceded the letter "b" then two digits, and followed by "3d".
Assuming you want to separate by last having 'b' and two digits followed by 3d, two digits or the end of string (this is necessary) and by omitting leading dot, you could take the following regular expression.
const
string = "Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25.",
result = string.match(/[^.].*?b\d\d(?=\.(3d|\D\D|$))/g);
console.log(result);
My regular expression:
/(?!#REF!)([^!,]{1,99})!/g
My test string:
foo,#REF!,bar!,baz,qux!
It currently matches REF! but the desired outcome is for only bar! and qux! to be matched. I used the negative look-ahead (?!#REF!) to prevent that but REF! is being captured as is matches [^!,]{1,99}.
How can prevent REF! getting matched - is using a negative look-ahead the correct approach?
Since your string is a comma separated item list, you may split the string with a comma, remove all empty items (if any), get only those ending with a ! and then remove the ! from the end of the strings:
var s = "foo,#REF!,bar!,baz,qux!";
console.log(s.split(',')
.filter(Boolean) // remove empty items
.filter(function (x) {return x.charAt(x.length-1)==="!" && x!== "#REF!";} ) // ends with ! and not #REF!
.map(function(y) {return y.substr(0, y.length-1)}) // remove !
);
If for some reason you still need to use a regex, you may use
/(?:^|,)(?!#REF!)([^!,]{1,99})!/g
Access Group 1 value. See the regex demo here.
NOTE: You only have 1 capturing group here, as (?!...) is a lookahead that is a special regex construct. (?:...) is a non-capturing group, its value is not stored in any additional memory buffer as compared to a capturing group.
Details
(?:^|,) - either start of string or ,
(?!#REF!) - no #REF! is allowed to appear right after the current location
([^!,]{1,99}) - Capturing group 1: 1 to 99 chars other than ! and ,
! - a ! char
var s = "foo,#REF!,bar!,baz,qux!";
var rx = /(?:^|,)(?!#REF!)([^!,]{1,99})!/g, m, res=[];
while (m=rx.exec(s)) {
res.push(m[1]);
}
console.log(res);
You can use the following regex:
(?<=^|,)(?!#REF!)([^!,]{1,99})!
Explanations:
Adding (?<=^|,) forces the start of your regex matching to either the beginning of the line or to the previous comma. If you don't add it REF! will also be matched. The , will not be part of the result because it is in a lookbehind clause.
DEMO
If you can not use lookbehind, then you can go for a solution like the one proposed by WiktorStribizew
(?:^|,)(?!#REF!)([^!,]{1,99}!)
and by referencing to the 1st capturing group
I'm trying to come up with a Regexp that detects whether a string in Javascript is trimmed or not. That means, it doesn't have whitespace at the beginning or end.
So far I have
^[^\s].*[^\s]$
This works if the string is long, but for short strings such as a, it will not work because the pattern wants a non-space, any character, then another non-space. That a is trimmed, but doesn't follow the pattern.
Help me find the correct regex.
Try this to make a second char optional:
^[^\s](.*[^\s])?$
One option is to take your existing regex (^[^\s].*[^\s]$) and add a separate part to it specifically to test for a single non-space character (^[^\s]$), combining the two parts with |:
/(^[^\s]$)|(^[^\s].*[^\s]$)/
But I find sometimes it is simpler to test for the opposite case and then invert the result with !. So in your case, have the regex test for a space at the beginning or end:
!/(^\s)|(\s$)/.test(someString)
Encapsulated in a function:
function isTrimmed(s) {
return !/(^\s)|(\s$)/.test(s)
}
console.log(isTrimmed(" a ")) // false
console.log(isTrimmed("a ")) // false
console.log(isTrimmed(" a")) // false
console.log(isTrimmed("a")) // true
console.log(isTrimmed("abc")) // true
console.log(isTrimmed("a b c")) // true
console.log(isTrimmed("")) // true
You can use the below regex :
^([\s]+[\w]*)?([\w]*[\s]+)?$
Might not be the nicest answer but Negative lookahead should work:
/^(?!(?:.*\s$)|(?:^\s.*)).*$/
(?=^\S)[\W\w]*\S$
(?=^\S) Lookahead for non-space character at the start of the string (matches without consuming the string; will start match from first character again)
[\W\w]* Match any number of characters
\S$ Match non-space character at the end of the string
So for a:
(?=^\S) Matches a at the start of the string (resets current position to the start of the string)
[\W\w]* Matches no characters, as it needs to match the next part
\S$ Matches a at the end of the string
I am stuck with creating regex such that if the word is preceded or ended by special character more than one regex on each side regex 'exec' method should throw null. Only if word is wrap with exactly one bracket on each side 'exec' method should give result Below is the regular expression I have come up with.
If the string is like "(test)" or then only regex.exec should have values for other combination such as "((test))" OR "((test)" OR "(test))" it should be null. Below code is not throwing null which it should. Please suggest.
var w1 = "\(test\)";
alert(new RegExp('(^|[' + '\(\)' + '])(' + w1 + ')(?=[' + '\(\)' + ']|$)', 'g').exec("this is ((test))"))
If you have a list of words and want to filter them, you can do the following.
string.split(' ').filter(function(word) {
return !(/^[!##$%^&*()]{2,}.+/).test(word) || !(/[!##$%^&*()]{2,}$).test(word)
});
The split() function splits a string at a space character and returns an array of words, which we can then filter.
To keep the valid words, we will test two regex expressions to see if the word starts or ends with 2 or more special characters respectively.
RegEx Breakdown
^ - Expression starts with the following
[] - A single character in the block
!##$%^&*() - These are the special characters I used. Replace them with the ones you want.
{2,} - Matches 2 or more of the preceeding characters
.+ - Matches 1 or more of any character
$ - Expression ends with the following
To use the exec function this way do this
!(/^[!##$%^&*()]{2,}.+/).exec(string) || !(/[!##$%^&*()]{2,}$).exec(string)
If I understand correctly, you are looking for any string which contains (test), anywhere in it, and exactly that, right?
In that case, what you probably need is the following:
var regExp = /.*[^)]\(test\)[^)].*/;
alert(regExp.exec("this is ((test))")); // → null
alert(regExp.exec("this is (test))" )); // → null
alert(regExp.exec("this is ((test)" )); // → null
alert(regExp.exec("this is (test) ...")); // → ["this is (test) ..."]
Explanation:
.* matches any character (except newline) between zero and unlimited times, as many times as possible.
[^)] match a single character but not the literal character )
This makes sure there's your test string in the given string, but it is only ever wrapped with one brace in every side!
You can use the following regex:
(^|[^(])(\(test\))(?!\))
See regex demo here, replace with $1<span style="new">$2</span>.
The regex features an alternation group (^|[^(]) that matches either start of string ^ or any character other than (. This alternation is a kind of a workaround since JS regex engine does not support look-behinds.
Then, (\(test\)) matches and captures (test). Note the round brackets are escaped. If they were not, they would be treated as a capturing group delimiters.
The (?!\)) is a look-ahead that makes sure there is no literal ) right after test). Look-aheads are supported fully by JS regex engine.
A JS snippet:
var re = /(^|[^(])(\(test\))(?!\))/gi;
var str = 'this is (test)\nthis is ((test))\nthis is ((test)\nthis is (test))\nthis is ((test\nthis is test))';
var subst = '$1<span style="new">$2</span>';
var result = str.replace(re, subst);
alert(result);
I'm maintaining some old code when I reached a headscratcher. I am confused by this regex pattern: /^.*$/ (as supplied as an argument in textFieldValidation(this,'true',/^.*$/,'','').
I interpret this regex as:
/^=open pattern
.=match a single character of any value (Except EOL)
*=match 0 or more times
$=match end of the line
/=close pattern
So…I think this pattern matches everything, which means the function does nothing but waste processing cycles. Am I correct?
It matches a single line of text.
It will fail to match a multiline String, because ^ matches the begining of input, and $ matches the end of input. If there are any new line (\n) or caret return (\r) symbols in between - it fails.
For example, 'foo'.match(/^.*$/) returns foo.
But 'foo\nfoo'.match(/^.*$/) returns null.
^ "Starting at the beginning."
. "Matching anything..."
* "0 or more times"
$ "To the end of the line."
Yep, you're right on, that matches empty or something.
And a handy little cheat sheet.
The regexp checks that the string doesn't contain any \n or \r. Dots do not match new-lines.
Examples:
/^.*$/.test(""); // => true
/^.*$/.test("aoeu"); // => true
/^.*$/.test("aoeu\n"); // => false
/^.*$/.test("\n"); // => false
/^.*$/.test("aoeu\nfoo"); // => false
/^.*$/.test("\nfoo"); // => false
Yes, you are quite correct. This regex matches any string that not contains EOL (if dotall=false) or any string (if dotall=true)