I have two dates:
var first = '21-11-2012';
var second = '03-11-2012';
What is the best way to format it like this:
var first = '2012-11-21';
var second = '2012-11-03';
Should I use jQuery or simply JavaScript?
You don't need jQuery for this, simply use JavaScript like so:
function formatDate(d){
return d.split('-').reverse().join('-');
}
Although if you want more reusable code consider using the JavaScript Date Object.
No need to be thinking of jQuery for basic string manipulation: the standard JS String methods are more than adequate, which (I assume) is why jQuery doesn't actually have equivalent methods.
A regex .replace() or the split/reverse/join concept in the other answers can both do it in one line. I'd recommend getting familiar with the methods at the MDN page I linked to, but meanwhile:
first = first.replace(/^(\d\d)-(\d\d)-(\d\d\d\d)$/,"$3-$2-$1");
(Same for second - encapsulate in a function if desired.)
This uses a regular expression to match the different parts of the date and reverse them.
UPDATE - As requested, an explanation of the regex I used:
^ // match beginning of string
(\d\d) // match two digits, and capture them for use
// in replacement expression as $1
- // match the literal hyphen character
(\d\d) // match two digits, and capture for use as $2
- // match the literal hyphen character
(\d\d\d\d) // match four digits, and capture for use as $3
$ // match end of string
Because the pattern matches from beginning to end of string the whole string will be replaced. The parts of the expression in parentheses are "captured" and can be referred to as $1, $2, etc. (numbered in the order they appear in the expression) if used in the replacement string, so "$3-$2-$1" reverses the order of these captured pieces and puts hyphens between them. (If the input string didn't meet that format the regex would not match and no replacement would be made.)
first=first.split("-").reverse().join("-")
second=second.split("-").reverse().join("-")
Related
I am trying to highlight sentences that contain a given word. Let's say for this example that the word is "lorem". To me a sentence can end multiple ways, for example, it can end with one of the following characters: "," "!" "." "?". This can be done very easy with the following regex:
/\b((?!=|\,|\.).)+(.)\b/gim
Previous I used /^.*lorem.*?(\.|\!|\?)/gim to match sentences containing the word "lorem". But this did not work most of the time as expected. Is there any way I can use the new regex that separates sentences to only match sentences with a given word?
Just a heads up. I understand that this could be accomplished using javascript functions like replace. However, this is not an option. Our custom system, where this regex is going to be used only accepts regex as input.
You can dynamically construct your RegExp from a target string using this function:
function sentenceWith (word) {
return new RegExp(String.raw`(?:[a-z\d][^=!?,.]*?|)\b${word}\b[^=!?,.]*`, 'gi');
}
This should be like Wiktor Stribiżew's suggestion except starting matches always begin with letter or number. It assumes that the input is alphanumeric string. If the input word can contain special characters, you should sanitize it using the answer in Is there a RegExp.escape function in Javascript? before feeding it to the constructor.
I try to extract all text from document title before it gets to closest "|" or "-" or "/" . I assume i have to write something like this but im not good at regex.
var docTitle = document.title();
docTitle.match(regex);
Can someone help me with correct regex or suggest perhaps a better solution to achieve desired effect ?
Thank you !
Use var shortTitle = document.title.split(/[|\/-]/,1)[0];
The split function divides a string into an array based on a separator.
You can pass a Regular Expression object into the split function if the separator is a pattern and not constant.
The regular expression is [|/-] meaning any |, /, or -. The / needed to be escaped with a \ in JavaScript because / is also the character that delimits Regular Expression literals.
The first element of the split array ([0]) will be the document title before the first occurrence of any of those separator characters.
It will be the only element in the array, because we told the split function to stop after the first occurrence.
If the document title contains no matching characters to split on, the split function returns the whole string in the first array element, anyway.
My goal is to get the length till the nth occurrence of <br> tag in javascript so I am splitting them up.
I am trying regex
((.|\s)*?<br\s?/?>){2} //2 is the max number of lines(br tags) allowed.
While this is working fine in regexBuddy
but the string is splitted into multiple parts ignoring the <br\s?/?> part in browser.
you can view a fiddle here
What am I doing wrong
Wouldn't exec make more sense than split in this case?
var str=$('#op').html();
var match = /((.|\s)*?<br\s?\/?>){2}/i.exec(str);
if( match )
console.log(match[0].length);
The issue is that you are using the split() method, which will split the string up in to pieces based on the regular expression. This will not include your regular expression match. In your case the first section of the string matches your regular expression, so you would have an empty string at index 0 and everything after the regular expression match in index 1.
You should try to use the match() method instead, which will return an array of the pieces of the string that matched your regular expression.
var str=$('#op').html();
console.log(str.match(/(([\s\S])*?<br\s?\/?>){2}/i)[0].length);
See code.
I'm trying to write a regular expression in JS to recognize any digit up to seven times, followed by a "-" followed by 2 digits followed by "-" followed by a single digit. This is the simple regex I have:
/\d{1,7}-\d{2}-\d/g
This should match strings like:
123-12-7
1-12-7
1234567-12-7
but not 12345678-12-1
However, the above is returning true. The regex returns true when there is any number of digit in the first group.
Does the JavaScript Regex object not support {n,m}?
Here is an example of what I am talking about.
var pattern = new RegExp(/\d{1,7}-\d{2}-\d/);
alert(pattern.test("12345678-13-1"));
http://jsfiddle.net/XTRAc/1/ live example
It matches 2345678-13-1. You need to anchor it to the beginning and end of your string:
/^\d{1,7}-\d{2}-\d$/
Note though, that (as Rocket Hazmat pointed out) you do not need to use the RegExp constructor if you use a regex literal (something without string quotes).
JSFiddle
It does support the {min,max}-syntax, but .match and .test() try to find matching substrings. You will have to include start and end anchors. Also notice that you should either use the RegExp constructor to build a regex from a string or a regex literal, but not both (see MDN: creating regexes).
/^\d{1,7}-\d{2}-\d$/
new RegExp("^\\d{1,7}-\\d{2}-\\d$") // the worse choice
You are constructing your regex incorrectly. Try this (note the anchors, which ensure the string consists of nothing but your pattern):
var pattern= /^\d{1,7}-\d{2}-\d$/;
Otherwise subsets of the existing string will match your regex.
If you need to validate entire input string, use regex pattern
/^\d{1,7}-\d{2}-\d$/
If you need to validate entire line of input string, use regex pattern
/^\d{1,7}-\d{2}-\d$/mg
If you need to find matches within input string, use regex pattern
/(?:\D|^)(\d{1,7}-\d{2}-\d)(?!\d)/g
...and use $1 as a result.
It does support the {n,m} part, the problem here is that your example matches 2345678, so you would need a way of matching the character before the first set of digits
I am trying to build a regexp from static text plus a variable in javascript. Obviously I am missing something very basic, see comments in code below. Help is very much appreciated:
var test_string = "goodweather";
// One regexp we just set:
var regexp1 = /goodweather/;
// The other regexp we built from a variable + static text:
var regexp_part = "good";
var regexp2 = "\/" + regexp_part + "weather\/";
// These alerts now show the 2 regexp are completely identical:
alert (regexp1);
alert (regexp2);
// But one works, the other doesn't ??
if (test_string.match(regexp1))
alert ("This is displayed.");
if (test_string.match(regexp2))
alert ("This is not displayed.");
First, the answer to the question:
The other answers are nearly correct, but fail to consider what happens when the text to be matched contains a literal backslash, (i.e. when: regexp_part contains a literal backslash). For example, what happens when regexp_part equals: "C:\Windows"? In this case the suggested methods do not work as expected (The resulting regex becomes: /C:\Windows/ where the \W is erroneously interpreted as a non-word character class). The correct solution is to first escape any backslashes in regexp_part (the needed regex is actually: /C:\\Windows/).
To illustrate the correct way of handling this, here is a function which takes a passed phrase and creates a regex with the phrase wrapped in \b word boundaries:
// Given a phrase, create a RegExp object with word boundaries.
function makeRegExp(phrase) {
// First escape any backslashes in the phrase string.
// i.e. replace each backslash with two backslashes.
phrase = phrase.replace(/\\/g, "\\\\");
// Wrap the escaped phrase with \b word boundaries.
var re_str = "\\b"+ phrase +"\\b";
// Create a new regex object with "g" and "i" flags set.
var re = new RegExp(re_str, "gi");
return re;
}
// Here is a condensed version of same function.
function makeRegExpShort(phrase) {
return new RegExp("\\b"+ phrase.replace(/\\/g, "\\\\") +"\\b", "gi");
}
To understand this in more depth, follows is a discussion...
In-depth discussion, or "What's up with all these backslashes!?"
JavaScript has two ways to create a RegExp object:
/pattern/flags - You can specify a RegExp Literal expression directly, where the pattern is delimited using a pair of forward slashes followed by any combination of the three pattern modifier flags: i.e. 'g' global, 'i' ignore-case, or 'm' multi-line. This type of regex cannot be created dynamically.
new RegExp("pattern", "flags") - You can create a RegExp object by calling the RegExp() constructor function and pass the pattern as a string (without forward slash delimiters) as the first parameter and the optional pattern modifier flags (also as a string) as the second (optional) parameter. This type of regex can be created dynamically.
The following example demonstrates creating a simple RegExp object using both of these two methods. Lets say we wish to match the word "apple". The regex pattern we need is simply: apple. Additionally, we wish to set all three modifier flags.
Example 1: Simple pattern having no special characters: apple
// A RegExp literal to match "apple" with all three flags set:
var re1 = /apple/gim;
// Create the same object using RegExp() constructor:
var re2 = new RegExp("apple", "gim");
Simple enough. However, there are significant differences between these two methods with regard to the handling of escaped characters. The regex literal syntax is quite handy because you only need to escape forward slashes - all other characters are passed directly to the regex engine unaltered. However, when using the RegExp constructor method, you pass the pattern as a string, and there are two levels of escaping to be considered; first is the interpretation of the string and the second is the interpretation of the regex engine. Several examples will illustrate these differences.
First lets consider a pattern which contains a single literal forward slash. Let's say we wish to match the text sequence: "and/or" in a case-insensitive manner. The needed pattern is: and/or.
Example 2: Pattern having one forward slash: and/or
// A RegExp literal to match "and/or":
var re3 = /and\/or/i;
// Create the same object using RegExp() :
var re4 = new RegExp("and/or", "i");
Note that with the regex literal syntax, the forward slash must be escaped (preceded with a single backslash) because with a regex literal, the forward slash has special meaning (it is a special metacharacter which is used to delimit the pattern). On the other hand, with the RegExp constructor syntax (which uses a string to store the pattern), the forward slash does NOT have any special meaning and does NOT need to be escaped.
Next lets consider a pattern which includes a special: \b word boundary regex metasequence. Say we wish to create a regex to match the word "apple" as a whole word only (so that it won't match "pineapple"). The pattern (as seen by the regex engine) needs to be: \bapple\b:
Example 3: Pattern having \b word boundaries: \bapple\b
// A RegExp literal to match the whole word "apple":
var re5 = /\bapple\b/;
// Create the same object using RegExp() constructor:
var re6 = new RegExp("\\bapple\\b");
In this case the backslash must be escaped when using the RegExp constructor method, because the pattern is stored in a string, and to get a literal backslash into a string, it must be escaped with another backslash. However, with a regex literal, there is no need to escape the backslash. (Remember that with a regex literal, the only special metacharacter is the forward slash.)
Backslash SOUP!
Things get even more interesting when we need to match a literal backslash. Let's say we want to match the text sequence: "C:\Program Files\JGsoft\RegexBuddy3\RegexBuddy.exe". The pattern to be processed by the regex engine needs to be: C:\\Program Files\\JGsoft\\RegexBuddy3\\RegexBuddy\.exe. (Note that the regex pattern to match a single backslash is \\ i.e. each must be escaped.) Here is how you create the needed RegExp object using the two JavaScript syntaxes
Example 4: Pattern to match literal back slashes:
// A RegExp literal to match the ultimate Windows regex debugger app:
var re7 = /C:\\Program Files\\JGsoft\\RegexBuddy3\\RegexBuddy\.exe/;
// Create the same object using RegExp() constructor:
var re8 = new RegExp(
"C:\\\\Program Files\\\\JGsoft\\\\RegexBuddy3\\\\RegexBuddy\\.exe");
This is why the /regex literal/ syntax is generally preferred over the new RegExp("pattern", "flags") method - it completely avoids the backslash soup that can frequently arise. However, when you need to dynamically create a regex, as the OP needs to here, you are forced to use the new RegExp() syntax and deal with the backslash soup. (Its really not that bad once you get your head wrapped 'round it.)
RegexBuddy to the rescue!
RegexBuddy is a Windows app that can help with this backslash soup problem - it understands the regex syntaxes and escaping requirements of many languages and will automatically add and remove backslashes as required when pasting to and from the application. Inside the application you compose and debug the regex in native regex format. Once the regex works correctly, you export it using one of the many "copy as..." options to get the needed syntax. Very handy!
You should use the RegExp constructor to accomplish this:
var regexp2 = new RegExp(regexp_part + "weather");
Here's a related question that might help.
The forward slashes are just Javascript syntax to enclose regular expresions in. If you use normal string as regex, you shouldn't include them as they will be matched against. Therefore you should just build the regex like that:
var regexp2 = regexp_part + "weather";
I would use :
var regexp2 = new RegExp(regexp_part+"weather");
Like you have done that does :
var regexp2 = "/goodweather/";
And after there is :
test_string.match("/goodweather/")
Wich use match with a string and not with the regex like you wanted :
test_string.match(/goodweather/)
While this solution may be overkill for this specific question, if you want to build RegExps programmatically, compose-regexp can come in handy.
This specific problem would be solved by using
import {sequence} from 'compose-regexp'
const weatherify = x => sequence(x, /weather/)
Strings are escaped, so
weatherify('.')
returns
/\.weather/
But it can also accept RegExps
weatherify(/./u)
returns
/.weather/u
compose-regexp supports the whole range of RegExps features, and let one build RegExps from sub-parts, which helps with code reuse and testability.