A lookahead (that (?= part) does not consume any input. It is a zero-width assertion (as are boundary checks and lookbehinds).
You want a regular match here, to consume the cow portion. To capture the portion in between, you use a capturing group (just put the portion of pattern you want to capture inside parenthesis):
cow(.*)milk
No lookaheads are needed at all.
Answer from R. Martinho Fernandes on Stack OverflowA lookahead (that (?= part) does not consume any input. It is a zero-width assertion (as are boundary checks and lookbehinds).
You want a regular match here, to consume the cow portion. To capture the portion in between, you use a capturing group (just put the portion of pattern you want to capture inside parenthesis):
cow(.*)milk
No lookaheads are needed at all.
Regular expression to get a string between two strings in JavaScript
The most complete solution that will work in the vast majority of cases is using a capturing group with a lazy dot matching pattern. However, a dot . in JavaScript regex does not match line break characters, so, what will work in 100% cases is a [^] or [\s\S]/[\d\D]/[\w\W] constructs.
ECMAScript 2018 and newer compatible solution
In JavaScript environments supporting ECMAScript 2018, s modifier allows . to match any char including line break chars, and the regex engine supports lookbehinds of variable length. So, you may use a regex like
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
In both cases, the current position is checked for cow with any 1/0 or more whitespaces after cow, then any 0+ chars as few as possible are matched and consumed (=added to the match value), and then milk is checked for (with any 1/0 or more whitespaces before this substring).
Scenario 1: Single-line input
This and all other scenarios below are supported by all JavaScript environments. See usage examples at the bottom of the answer.
cow (.*?) milk
cow is found first, then a space, then any 0+ chars other than line break chars, as few as possible as *? is a lazy quantifier, are captured into Group 1 and then a space with milk must follow (and those are matched and consumed, too).
Scenario 2: Multiline input
cow ([\s\S]*?) milk
Here, cow and a space are matched first, then any 0+ chars as few as possible are matched and captured into Group 1, and then a space with milk are matched.
Scenario 3: Overlapping matches
If you have a string like >>>15 text>>>67 text2>>> and you need to get 2 matches in-between >>>+number+whitespace and >>>, you can't use />>>\d+\s(.*?)>>>/g as this will only find 1 match due to the fact the >>> before 67 is already consumed upon finding the first match. You may use a positive lookahead to check for the text presence without actually "gobbling" it (i.e. appending to the match):
/>>>\d+\s(.*?)(?=>>>)/g
See the online regex demo yielding text1 and text2 as Group 1 contents found.
Also see How to get all possible overlapping matches for a string.
Performance considerations
Lazy dot matching pattern (.*?) inside regex patterns may slow down script execution if very long input is given. In many cases, unroll-the-loop technique helps to a greater extent. Trying to grab all between cow and milk from "Their\ncow\ngives\nmore\nmilk", we see that we just need to match all lines that do not start with milk, thus, instead of cow\n([\s\S]*?)\nmilk we can use:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
See the regex demo (if there can be \r\n, use /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm). With this small test string, the performance gain is negligible, but with very large text, you will feel the difference (especially if the lines are long and line breaks are not very numerous).
Sample regex usage in JavaScript:
Run code snippetEdit code snippet Hide Results Copy to answer Expand//Single/First match expected: use no global modifier and access match[1] console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]); // Multiple matches: get multiple matches with a global modifier and // trim the results if length of leading/trailing delimiters is known var s = "My cow always gives milk, thier cow also gives milk"; console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);})); //or use RegExp#exec inside a loop to collect all the Group 1 contents var result = [], m, rx = /cow (.*?) milk/g; while ((m=rx.exec(s)) !== null) { result.push(m[1]); } console.log(result);
Using the modern
String#matchAllmethodRun code snippetEdit code snippet Hide Results Copy to answer Expandconst s = "My cow always gives milk, thier cow also gives milk"; const matches = s.matchAll(/cow (.*?) milk/g); console.log(Array.from(matches, x => x[1]));
regex - Get Substring between two characters using JavaScript - Stack Overflow
javascript - Regex get all content between two characters - Stack Overflow
javascript - Regex to get the text between two characters? - Stack Overflow
How do I match a string between characters in javascript regex - Stack Overflow
Try this:
test.match(new RegExp(firstvariable + "(.*)" + secondvariable));
Use this code
const regExString = new RegExp(`(?<=${firstVariable}).*?(?=${secondVariable})`, "ig"); //set ig flag for global search and case insensitive
const testRE = regExString.exec("My cow always gives milk.");
if (testRE && testRE.length > 0) //RegEx has found something and has at least one entry.
{
alert(testRE[0]); //is the matched group if found
}
This matches only the middle part of the sentence.
(?<="+firstvariable+")finds but does not capturecow::lookbehindis possible now..*?captures all characters betweencowandmilkand saves it in a group.?makes it lazy so it stops at milk.(?="+secondvariable+")finds but does not capturemilk. ::lookahead
You can test this below:
const test = document.getElementById("testStringDiv").textContent;
let firstVariable = "";
let secondVariable = "";
function testString()
{
firstVariable = document.querySelectorAll("input")[0].value; //first input;
secondVariable = document.querySelectorAll("input")[1].value; //second input;
//build the regex:
//lookbehind is possible in JavaScript now: (?<=) sees if the content in the matched group is preceded by the first variable, but does not capture this.
//for the second variable we use the (?=) which is a lookahead and does the same as the lookbehind.
//If there is a match, the string returned will be the one in the captured group (.*?)
let regExString = new RegExp(`(?<=${firstVariable}).*?(?=${secondVariable})`, "ig");
const testRE = regExString.exec(test);
if (testRE && testRE.length > 0)
{
document.getElementById("showcase").textContent = testRE[0]; //return second result.
}
}
document.getElementById("test").addEventListener("click", testString, true);
<div id="testStringDiv">My cow always gives milk</div>
<div id="showcase">Result will display here...</div>
<input placeholder="enter first var"/><input placeholder="enter second var"/><button id="test">Search in between...</button>
var regex = /\[\[(.*?)\]\]/g;
var input = 'Hello, my my [[name]] is [[Joffrey]]';
var match;
do {
match = regex.exec(input);
if (match) {
console.log(match[1]);
}
} while (match);
Will print both matches in your console. Depending on whether you want to print out even blank values you would want to replace the "*" with a "+" /\[\[(.+?)\]\]/g.
Here is the regex:
/\[\[(.*?)\]]/g
Explanation:
\[ Escaped character. Matches a "[" character (char code 91).
( Groups multiple tokens together and creates a capture group for extracting a substring or using a backreference.
. Dot. Matches any character except line breaks.
* Star. Match 0 or more of the preceding token.
? Lazy. Makes the preceding quantifier lazy, causing it to match as few characters as possible.
)
\] Escaped character. Matches a "]" character (char code 93).
] Character. Matches a "]" character (char code 93).
Like i said in the comment, you don't need to escape / symbol in the character class. And also you don't need even a character class also. Just \/ would be enough. The below regex would capture one or more numbers which are preceded by / symbol and followed by _ symbol.
\/(\d+)_
DEMO
> var image_id = image_url.match(/\/(\d+)_/)[1]
undefined
> image_id
'14628998490'
OR
You could try this also, if you don't want to give \d+ in your pattern.
\/([^/]*?)_
DEMO
> var image_id = image_url.match(/\/([^/]*?)_/)[1]
undefined
> image_id
'14628998490'
Not shure that it's is better way, but you can do like this:
var str = 'http://farm4.staticflickr.com/3877/[image_id]_[secret].jpg';
var image_id = str.split('/').pop().split('.')[0].split('_');
URLSearchParams would make things significantly easier:
const query1 = '?someBoolean=false&q=&location=&testParam=dummy_value&testParam2=dummy_value2&requiredParam=requiredValue';
const query2 = '?someBoolean=false&q=&location=&testParam=dummy_value&testParam2=dummy_value2&requiredParam=requiredValue&someMoreParam=dummy_value2';
const params1 = new URLSearchParams(query1);
const params2 = new URLSearchParams(query2);
console.log(`For Query1: result = ${params1.get('requiredParam')}`);
console.log(`For Query2: result = ${params2.get('requiredParam')}`);
It's supported natively in the vast majority of browsers, but not all. For the rest, here's a polyfill. It's better not to re-invent the wheel when you don't need to, and it's good when you're able to use a standard API (with examples and documentation and Stack Overflow answers about it, etc).
As a side note - when using regular expressions, I'd recommend using capture groups only when necessary. If all you need to do is group some tokens together logically (like for a | alternation), non-capturing groups should be preferred. That is, if URLSearchParams didn't exist, better to do (?:&|$) than (&|$). Reserve capturing groups for when you need to save and use the captured result somewhere - otherwise, non-capturing groups are more appropriate, less expensive, and require less cognitive overhead.
If you had to go the regex route, another slight improvement would be to use a negative character class instead of lazy repetition. In the pattern, you have:
(.*?)(&|$)
Lazy repetition is slow; it forces the engine to advance one character at a time, then check the rest of the pattern for a match, and repeat until the match is found. Since you know that the capture group will not contain any &s, better to match anything but &s:
([^&]*)
Once you do that, you don't even need the final (&|$) or (?:&|$) due to the greedy repetition.
Bug with variable declarations
The keywords const and let are only supported (partially) by IE 111 2.
I don't have IE 9 but I do have IE 11 and set the Document mode to IE 9.

Running the first line in a sandbox on jsBin.com :
const query1 = '?someBoolean=false&q=&location=&testParam=dummy_value&testParam2=dummy_value2&requiredParam=requiredValue';
led to an error in the console:

In order to properly support IE 9 users, use var instead of const and let.
Easy done:
(?<=\[)(.*?)(?=\])
Technically that's using lookaheads and lookbehinds. See Lookahead and Lookbehind Zero-Width Assertions. The pattern consists of:
- is preceded by a
[that is not captured (lookbehind); - a non-greedy captured group. It's non-greedy to stop at the first
]; and - is followed by a
]that is not captured (lookahead).
Alternatively you can just capture what's between the square brackets:
\[(.*?)\]
and return the first captured group instead of the entire match.
If you are using JavaScript, the solution provided by cletus, (?<=\[)(.*?)(?=\]) won't work because JavaScript doesn't support the lookbehind operator.
Edit: actually, now (ES2018) it's possible to use the lookbehind operator. Just add / to define the regex string, like this:
var regex = /(?<=\[)(.*?)(?=\])/;
Old answer:
Solution:
var regex = /\[(.*?)\]/;
var strToMatch = "This is a test string [more or less]";
var matched = regex.exec(strToMatch);
It will return:
["[more or less]", "more or less"]
So, what you need is the second value. Use:
var matched = regex.exec(strToMatch)[1];
To return:
"more or less"