When i use regex function for title and caption then it works but when I add more matching tags then it not works
here is the code below which works fine without any problem
$(".sidebar").each(function() {
var e = $(this),
t = e.find(".widget").text();
if (t) {
var a = t.match(/title=\(([^)]*)\)\s caption=\(([^)]*)\)/);
alert(t);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sidebar'>
<div class='widget'>title=(example1) caption=(example2)</div>
</div>
But the problem is when I try to use multiple matching tags then it does not works like
<div class='widget'>title=(example1) caption=(example2) button=(example3) price=(example4) off=(example5)</div>
I tried hard to use regex same like above for this values but it didn't work
I also want to add these examples text and the Output look like is example1 example2 example3 example4 example5 but I have no idea done with regex function
any help or advice is highly appreciated
CodePudding user response:
Instead of using match()
, consider using exec()
, which will allow you to access the capture groups as well. Your capture group should ideally capture the value inside the parenthesis coming after the =
character, so you can write your regex pattern as such:
var re = /\w ?=\((.*?)\)/gi;
Then, it is simply a matter of running a while
loop to recursively invoke the exec()
method until no more matches can be found:
$(".sidebar").each(function() {
var e = $(this);
var t = e.find(".widget").text();
if (t) {
var result;
var results = [];
var re = /\w ?=\((.*?)\)/gi;
while ((result = re.exec(t)) !== null) {
console.log(result[1]);
results.push(result[1]);
}
console.log('Logging all captured values:\n', results);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sidebar'>
<div class='widget'>title=(example1) caption=(example2) button=(example3) price=(example4) off=(example5)</div>
</div>
Even better: you don't even need jQuery for this:
document.querySelectorAll('.sidebar .widget').forEach(el => {
const t = el.innerText.trim();
if (t) {
let result;
const results = [];
const re = /\w ?=\((.*?)\)/gi;
while ((result = re.exec(t)) !== null) {
console.log(result[1]);
results.push(result[1]);
}
console.log('Logging all captured values:\n', results);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sidebar'>
<div class='widget'>title=(example1) caption=(example2) button=(example3) price=(example4) off=(example5)</div>
</div>
CodePudding user response:
Here's an example on how to get any value given this format:
Match anything that is not a
)
one or more times.
Must be preceded by\w =(
and must be followed by)
Better explained in This Regex101 Example
$(".sidebar").find(".widget").each(function() {
const txt = $.trim($(this).text()); // Get trimmed text
if (!txt) return; // Do nothing
const matches = txt.match(/(?<=\b\w =\()[^)] (?=\))/g)||[];
matches.forEach(m => {
console.log(m);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sidebar'>
<div class='widget'>title=(example1) caption=(example2) button=(example3) price=(example4) off=(example5)</div>
<div class="widget">ola</div>
<div class="widget"></div>
<div class="widget">The magic happens=(here) :)</div>
</div>
CodePudding user response:
In your code, you use alert(t);
which is the result from t = e.find(".widget").text();
If you use the result from var a = t.match(/title=\(([^)]*)\)\s caption=\(([^)]*)\)/);
then the regex will return a match for title=
and caption=
which either have a value in a capture group, but the match should be in that order.
You will get a single match as there is no /g
flag, and there is also only 1 occurrence in the example data.
What you could do is make your expression a bit less restrictive, and instead of matching specifically on title and capture, match 1 or more non whitespace characters other than an equals sign instead.
Use the /g
flag to get all the matches instead of a single match.
[^\s=] =\(([^)]*)\)
[^\s=]
Match 1 times any char other than=
or a whitespace char=
Match literally\(
Match(
([^)]*)
Capture in group 1 optional characters other than)
or use*
for 1 or more\)
Match)
A regex demo to see the captured group values:
$(".sidebar").each(function() {
var e = $(this),
t = e.find(".widget").text();
if (t) {
var a = t.matchAll(/[^\s=] =\(([^)]*)\)/g);
console.log(Array.from(a, m => m[1]));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sidebar'>
<div class='widget'>title=(example1) caption=(example2) button=(example3) price=(example4) off=(example5)</div>
</div>