This is the code:
isValid = field.uploads.forEach(upload => {
console.log(upload.file)
console.log('ext:', _.getFileExt(upload.file.name))
console.log('reg:', regex)
console.log('res:', regex.test(_.getFileExt(upload.file.name)))
})
These are the logs:
ext: jpg
reg: /^.*\.(.jpg)$/i
res: false
As you can see, even if the file is jpg the regex returns false. Why is this?
EDIT:
Here are the utility functions:
_.listToRegex = (array) => {
return new RegExp('^.*\\.(' + array.join('|') + ')$', 'i')
}
_.getFileExt = (string) => {
return string.split('.').pop()
}
You have two problems as far as I can tell. First, your regular expression has an error. Second, you have to decide whether the regular expression that you are creating is intended to match against file names or file extensions.
1. The regex that was logged to the console contains an extra period, as pointed out in the comments above. /^.*\.(.jpg)$/i could be condensed to /\.(jpg)$/i if you only intend to use the expression to test for validity. You did not seem to show the assignment of your regex variable, so it is difficult to gauge how exactly the error arose, but my best guess is that you called your listToRegex utility like:
var regex = _.listToRegex(['.jpg'])
The . in the string '.jpg' would cause the introduction of the extra period. You could replace that code with:
var regex = _.listToRegex(['jpg'])
2. Secondly, you seem to be testing your regular expression against the file extension, when I think you want to test it against a file name.
regex.test(upload.file.name) //=> true
Related
I am doing a challenge on freeCodeCamp. I am passed an array with 2 strings, the instructions are to test to see if the letters in the second string are in the first string.
Here's what I have:
return /[arr\[1\]]/gi.test(arr[0]);
This passes all the tests except where it tries to match with a capital letter.
mutation(["hello", "Hello"]) should return true.
It's the only test that fails, I have tested my regex on regexr.com with:
/[Hello]/gi and it matches with 'hello'.
Yes, there are other ways to do it, but why does it fail when I pass the string into the regex from the array?
EDIT: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/mutations
keep in mind that with this: return /[arr\[1\]]/gi.test(arr[0]) you are evaluating exactly this string "arr[1]". test() is a method of RegExp, then to add variables in a regex, or build the regex as string, you should use the RegExp constructor. Like the example below.
See this for browser compatibility of flags.
function mutation(str){
var r = new RegExp(str[0].toLowerCase(), "gi")
return r.test(str[1].toLowerCase());
}
console.log(mutation(["hello", "Hello"]))
The fact that your code passes the test for ["Mary", "Army"] shows that the problem is not one of case sensitivity. The only reason your code passes any of the tests is that /[arr\[1\]]/ looks for matches against the set of characters ar1[] which coincidentally happens to correctly match 8 of the 9 tests. Anyway the other - perhaps biggest - issue is that you are not testing all of the characters in arr[1] against arr[0]; if you run #Emeeus's answer it returns false positives for many of the tests. So, to test all of the characters in arr[1] against arr[0] you need something like this:
function mutation(arr) {
return arr[1].split('').reduce((t, c) => t && new RegExp(c, 'i').test(arr[0]), true);
}
let tests = [
['hello', 'hey'],
["hello", "Hello"],
["zyxwvutsrqponmlkjihgfedcba", "qrstu"],
["Mary", "Army"],
["Mary", "Aarmy"],
["Alien", "line"],
["floor", "for"],
["hello", "neo"],
["voodoo", "no"]
];
tests.map(arr => console.log(arr[0] + ", " + arr[1] + " => " + (mutation(arr) ? 'match' : 'no match')));
JavaScript has a special syntax for Regular Expressions. Those two lines are essentially the same:
return /[arr\[1\]]/gi.test(arr[0]);
return new RegExp('[arr\\[1\\]]', 'gi').test(arr[0]);
but what you probably want is this:
new RegExp('['+arr[1]+']', 'gi').test(arr[0]);
However, you should be careful since this approach does not work if it contains special characters such as '[' or ']'.
Whenever you have a javascript variable in a regular expression, you should construct a new RegExp object. Taken from your question, it should look like this
return new RegExp(arr[1], "gi").test(arr[0]);
As one hint on freeCodeCamp.org says, you can solve the problem easier if you transform the strings into arrays, using the spread operator. No need for regular expressions.
Instead of:
return /[arr\[1\]]/gi.test(arr[0]);
you can do:
return new RegEx(arr[1], gi);
Your code uses a character match ([ ]), not a string match, so it will match anything, that has those characters directly (That's why uppercase and lowercase differs, although you have specified 'i').
The new expression directly uses the string to match, not just the characters.
What are the actual uses of String.raw Raw String Access introduced in ECMAScript 6?
// String.raw(callSite, ...substitutions)
function quux (strings, ...values) {
strings[0] === "foo\n"
strings[1] === "bar"
strings.raw[0] === "foo\\n"
strings.raw[1] === "bar"
values[0] === 42
}
quux `foo\n${ 42 }bar`
String.raw `foo\n${ 42 }bar` === "foo\\n42bar"
I went through the below docs.
http://es6-features.org/#RawStringAccess
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw
http://www.2ality.com/2015/01/es6-strings.html
https://msdn.microsoft.com/en-us/library/dn889830(v=vs.94).aspx
The only the thing that I understand, is that it is used to get the raw string form of template strings and used for debugging the template string.
When this can be used in real time development? They were calling this a tag function. What does that mean?
What concrete use cases am I missing?
The best, and very nearly only, use case for String.raw I can think of is if you're trying to use something like Steven Levithan's XRegExp library that accepts text with significant backslashes. Using String.raw lets you write something semantically clear rather than having to think in terms of doubling your backslashes, just like you can in a regular expression literal in JavaScript itself.
For instance, suppose I'm doing maintenance on a site and I find this:
var isSingleUnicodeWord = /^\w+$/;
...which is meant to check if a string contains only "letters." Two problems: A) There are thousands of "word" characters across the realm of human language that \w doesn't recognize, because its definition is English-centric; and B) It includes _, which many (including the Unicode consortium) would argue is not a "letter."
So if we're using XRegExp on the site, since I know it supports \pL (\p for Unicode categories, and L for "letter"), I might quickly swap this in:
var isSingleUnicodeWord = XRegExp("^\pL+$"); // WRONG
Then I wonder why it didn't work, facepalm, and go back and escape that backslash, since it's being consumed by the string literal.
Easy enough in that simple regex, but in something complicated, remembering to double all those backslashes is a maintenance pain. (Just ask Java programmers trying to use Pattern.)
Enter String.raw:
let isSingleUnicodeWord = XRegExp(String.raw`^\pL+$`);
Example:
let isSingleUnicodeWord = XRegExp(String.raw`^\pL+$`); // L: Letter
console.log(isSingleUnicodeWord.test("Русский")); // true
console.log(isSingleUnicodeWord.test("日本語")); // true
console.log(isSingleUnicodeWord.test("العربية")); // true
console.log(isSingleUnicodeWord.test("foo bar")); // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.min.js"></script>
Now I just kick back and write what I mean. I don't even really have to worry about ${...} constructs used in template literals to do substitution, because the odds of my wanting to apply a quantifier {...} to the end-of-line assertion ($) are...low. So I can happily use substitutions and still not worry about backslashes. Lovely.
Having said that, though, if I were doing it a lot, I'd probably want to write a function and use a tagged template instead of String.raw itself. But it's surprisingly awkward to do correctly:
// My one-time tag function
function xrex(strings, ...values) {
let raw = strings.raw;
let max = Math.max(raw.length, values.length);
let result = "";
for (let i = 0; i < max; ++i) {
if (i < raw.length) {
result += raw[i];
}
if (i < values.length) {
result += values[i];
}
}
console.log("Creating with:", result);
return XRegExp(result);
}
// Using it, with a couple of substitutions to prove to myself they work
let category = "L"; // L: Letter
let maybeEol = "$";
let isSingleUnicodeWord = xrex`^\p${category}+${maybeEol}`;
console.log(isSingleUnicodeWord.test("Русский")); // true
console.log(isSingleUnicodeWord.test("日本語")); // true
console.log(isSingleUnicodeWord.test("العربية")); // true
console.log(isSingleUnicodeWord.test("foo bar")); // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.min.js"></script>
Maybe the hassle is worth it if you're using it in lots of places, but for a couple of quick ones, String.raw is the simpler option.
First, a few things:
Template strings is old name for template literals.
A tag is a function.
String.raw is a method.
String.raw `foo\n${ 42 }bar\` is a tagged template literal.
Template literals are basically fancy strings.
Template literals can interpolate.
Template literals can be multi-line without using \.
String.raw is required to escape the escape character \.
Try putting a string that contains a new-line character \n through a function that consumes newline character.
console.log("This\nis\nawesome"); // "This\nis\nawesome"
console.log(String.raw`This\nis\nawesome`); // "This\\nis\\nawesome"
If you are wondering, console.log is not one of them. But alert is. Try running these through http://learnharmony.org/ .
alert("This\nis\nawesome");
alert(String.raw`This\nis\nawesome`);
But wait, that's not the use of String.raw.
Possible uses of String.raw method:
To show string without interpretation of backslashed characters (\n, \t) etc.
To show code for the output. (As in example below)
To be used in regex without escaping \.
To print windows director/sub-directory locations without using \\ to much. (They use \ remember. Also, lol)
Here we can show output and code for it in single alert window:
alert("I printed This\nis\nawesome with " + Sring.raw`This\nis\nawesome`);
Though, it would have been great if It's main use could have been to get back the original string. Like:
var original = String.raw`This is awesome.`;
where original would have become: This\tis \tawesome.. This isn't the case sadly.
References:
http://exploringjs.com/es6/ch_template-literals.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw
Template strings can be useful in many situations which I will explain below. Considering this, the String.raw prevents escapes from being interpreted. This can be useful in any template string in which you want to contain the escape character but do not want to escape it. A simple example could be the following:
var templateWithBackslash = String.raw `someRegExp displayed in template /^\//`
There are a few things inside that are nice to note with template strings.
They can contain unescaped line breaks without problems.
They can contain "${}". Inside these curly braces the javascript is interpreted instead.
(Note: running these will output the result to your console [in browser dev tools])
Example using line breaks:
var myTemplate = `
<div class="myClass">
<pre>
My formatted text
with multiple lines
{
asdf: "and some pretty printed json"
}
</pre>
</div>
`
console.log(myTemplate)
If you wanted to do the above with a normal string in Javascript it would look like the following:
var myTemplate = "\
<div class="myClass">\
<pre>\
My formatted text\
with multiple lines\
{\
asdf: "and some pretty printed json"\
}\
</pre>\
</div>"
console.log(myTemplate)
You will notice the first probably looks much nicer (no need to escape line breaks).
For the second I will use the same template string but also insert the some pretty printed JSON.
var jsonObj = {asdf: "and some pretty printed json", deeper: {someDeep: "Some Deep Var"}}
var myTemplate = `
<div class="myClass">
<pre>
My formatted text
with multiple lines
${JSON.stringify(jsonObj, null, 2)}
</pre>
</div>
`
console.log(myTemplate)
In NodeJS it is extremely handy when it comes to filepath handling:
var fs=require('fs');
var s = String.raw`C:\Users\<username>\AppData\Roaming\SomeApp\someObject.json`;
var username = "bob"
s=s.replace("<username>",username)
fs.readFile(s,function(err,result){
if (err) throw error;
console.log(JSON.parse(result))
})
It improves readability of filepaths on Windows. \ is also a fairly common separator, so I can definitely see why it would be useful in general. However it is pretty stupid how \ still escapes `... So ultimately:
String.raw`C:\Users\` //#==> C:\Users\`
console.log(String.raw`C:\Users\`) //#==> SyntaxError: Unexpected end of input.
In addition to its use as a tag, String.raw is also useful in implementing new tag functions as a tool to do the interleaving that most people do with a weird loop. For example, compare:
function foo(strs, ...xs) {
let result = strs[0];
for (let i = 0; i < xs.length; ++i) {
result += useFoo(xs[i]) + strs[i + 1];
}
return result;
}
with
function foo(strs, ...xs) {
return String.raw({raw: strs}, ...xs.map(useFoo));
}
The Use
(Requisite knowledge: tstring §.)
Instead of:
console.log(`\\a\\b\\c\\n\\z\\x12\\xa9\\u1234\\u00A9\\u{1234}\\u{00A9}`);
.you can:
console.log(String.raw`\a\b\c\n\z\x12\xa9\u1234\u00A9\u{1234}\u{00A9}`);
"Escaping"
<\\u> is fine, yet <\u> needs "escaping", eg:
console.log(String.raw`abc${'\\u'}abc`);
.Dit <\\x>, <\x>,
<console.log(String.raw`abc${`\\x`}abc`)>;
.<\`>, <`>, <console.log(String.raw`abc${`\``}abc`)>;
.<\${>, <${&>, <console.log(String.raw`abc${`$\{`}abc`)>;
.<\\1> (till <\\7>), <\1>, <console.log(String.raw`abc${`\\1`}abc`)>;
.<\\>, endunit <\>, <console.log(String.raw`abc${`\\`}`)>.
Nb
There's also a new "latex" string. Cf §.
I've found it to be useful for testing
my RegExps. Say I have a RegExp which
should match end-of-line comments because
I want to remove them. BUT, it must not
match source-code for a regexp like /// .
If your code contains /// it is not the
start of an EOL comment but a RegExp, as
per the rules of JavaScript syntax.
I can test whether my RegExp in variable patEOLC
matches or doesn't /// with:
String.raw`/\//` .match (patEOLC)
In other words it is a way to let my
code "see" code the way it exists in
source-code, not the way it exists
in memory after it has been read
into memory from source-code, with
all backslashes removed.
It is a way to "escape escaping" but
without having to do it separately
for every backslash in a string, but
for all of them at the same time.
It is a way to say that in a given
(back-quoted) string backslash
shall behave just like any other
character, it has no special
meaning or interpretation.
So I have this regular expression:
(?:[ \t]*)?(?:\/\/|\/\*)[ \t]*#exclude[ \t]*([^\n*]*)[ \t]*(?:\*\/)?(?:[ \t]*[\r\n]+)?((?:.|\n|\r)*?)(?:[ \t]*)?(?:\/\/|\/\*)[ \t]*#endexclude[ \t]*(?:\*\/)?(?:[ \t]*[\r\n]+)?
Which is supposed to match anything that looks like this:
/* #exclude */
hurdur = somerandomtextorcode;
/* #endexclude */
I am trying this regular expression in tools such as https://regex101.com/ (https://regex101.com/r/eA5oK9/1) and there it just simply works, no errors.
However, in the nodejs environment, I get this error which I really do not know how to solve:
Warning: Invalid regular expression: /(?:[ ]*)?(?://|/*)[ ]*#exclude[
]*([^
]*)[ ]*(?:*/)?(?:[ ]*[
]+)?((?:.|
|
)?)(?:[ ]*)?(?://|/*)[ ]*#endexclude[ ]*(?:*/)?(?:[ ]*[
]+)?/: Nothing to repeat Use --force to continue.
Any help on this would be greatly appreciated!
Alright, it turns out it was a problem related to the way I was actually creating the regular expression.
I was creating (and applying) the regular expression like this:
var rExclude = '(?:[ \t]*)?(?:\/\/|\/\*)[ \t]*#exclude[ \t]*([^\n*]*)[ \t]*(?:\*\/)?(?:[ \t]*[\r\n]+)?((?:.|\n|\r)*?)(?:[ \t]*)?(?:\/\/|\/\*)[ \t]*#endexclude[ \t]*(?:\*\/)?(?:[ \t]*[\r\n]+)?';
contents = contents.replace(new RegExp(rExclude, 'gi'), function () { return ""; });
This gives me the error that is described in the starting post.
However, because the regular expression is in a string, JavaScript decides it wants to handle the regular expression differently. You can fix it in two ways:
Solution 1
This solution alters the way stuff is being escaped in your string.
var rExclude = '(?:[ \t]*)?(?://|/\\*)[ \t]*#exclude[ \t]*(?:\\*/)?(?:.|\n|\r)*?(?://|/\\*)[ \t]*#endexclude[ \t]*(?:\\*/)?';
contents = contents.replace(new RegExp(rExclude, 'gi'), function () { return ""; });
Solution 2
This solution alters the way the actual regular expression is being created:
contents = contents.replace(/(?:[ \t]*)?(?:\/\/|\/\*)[ \t]*#exclude[ \t]*(?:\*\/)?(?:.|\n|\r)*?(?:\/\/|\/\*)[ \t]*#endexclude[ \t]*(?:\*\/)?/gi, function () { return ""; });
It's just another weird ass JavaScript quirk, unfortunately.
Double-up your backslashes.
Notice how here: (?:*/)? there's no backslash? This means your * is trying to repeat.. nothing. Nothing to repeat.
so I've been running around regexp for a while now, and been using RegEx101 to test my patterns, and it never failed (yet).
So I am trying to replace android Emojicons strings to their appropriate HTML image tage via regex, the code seems to match without an issue in the site above, and even works with PHP, but somehow, it doesn't match at all in javascript... so here is my code:
function loadEmojisInMessage(message) {
var regExp = /({emoji:(.*?)})/g; //var regExp = new RegExp("({emoji:(.*?)})","g");
message.replace(regExp, '<img src="emojis/emoji_$2.png" id="$2" class="emojicon" />').toString();
return message;
}
at first I thought I am doing something wrong, so I changed the code to this, just for testing
function loadEmojisInMessage(message) {
var regExp = /({emoji:(.*?)})/g; //var regExp = new RegExp("({emoji:(.*?)})","g");
message.replace(regExp, 'test?').toString();
return message;
}
but even this does not replace at all! (my thought is that it is having an issue matching the pattern in the string :/ )
example strings to match :
{emoji:em_1f50f}
What I am trying to do here is replace the entire string (above) with image HTML tag, while using the second match [it is the second bracket () ] for the URL string
Best Regards
UPDATE :
I forgot to add first matching bracket, sorry!
Also, you can test the pattern here
You're not assigning the result of the replace() method call back to the variable message. If you don't to this, message remains unchanged.
message = message.replace(regExp, '<img src="emojis/emoji_$2.png" id="$2" class="emojicon" />');
Given a string, how can I match all e-mails thar are inside "< >".
For example:
I can have xxx#abc.com and <yyy#abc.com> and I only want to match the yyy#abc.com.
Thanks!
To be really thorough you could implement a regex from RFC822, which describes valid email address formats, however, you could save time and headache by doing something quick and simple like this:
var extractEmailAddress = function(s) {
var r=/<?(\S+#[^\s>]+)>?/, m=(""+s).match(r);
return (m) ? m[1] : undefined;
};
extractEmailAddress('xxx#abc.com'); // => "xxx#abc.com"
extractEmailAddress('<yyy#abc.com>'); // => "yyy#abc.com"
Of course, this function will be very permissive of strings that might conceivably even remotely look like an email address, so the regular expression "r" could be improved if quality is a concern.