WordPress' FacetWP plugin has a 'facetwp-loaded' jQuery event that allows for changes when facets are refreshed.
This is the 'facetwp-loaded' event's usage from FacetWP's documentation:
(function($) {
$(document).on('facetwp-loaded', function() {
// Changes go here
});
})(jQuery);
Facets produce URL's like:
http://website.com/hotels?fwp_location=worldwide
or
http://website.com/hotels/worldwide?fwp_location=europe
So I would like to make a global Regex redirection to substitute what is between
hotels
and
=
with
/
In the above examples, that would result in:
http://website.com/hotels/worldwide
or
http://website.com/hotels/europe
Can someone help me with this?
Thanks in advance
UPDATE
I've tried different Regex methods, but it seems to need jQuery parameter replace/update.
I don't have a way to test this using the Wordpress regex engine, so you'll have to check it, but it works in the R regex engine. Hopefully Wordpress supports perl style regex expressions.
Regex: Match: (?<=hotels).*?= and replace with /
In this case the piece of the string we want to remove is preceded by "hotels" and ends with an equal sign. So we want to match everything immediately after hotels, ending at the equal sign. To start matching immediately after "hotels" but not include it, we need to look backwards. So we use a look behind before the match. (?<=hotels) means look backwards from the current position in the string, and see if "hotels" precedes the current position. So when the engine gets to the "/" after hotels, it looks back and sees hotels (but it doesn't match, because it's a look behind). . matches any character, * means match zero or more (so zero or more of any character), and ? modifies the * telling the star to match zero or more characters, but only until the next character can be matched, in this case =.
Related
I have the following string that will occur repeatedly in a larger string:
[SM_g]word[SM_h].[SM_l] "
Notice in this string after the phrase "[SM_g]word[Sm_h]" there are three components:
A period (.) This could also be a comma (,)
[SM_l]
"
Zero to all three of these components will always appear after "[SM_g]word[SM_h]". However, they can also appear in any order after "[SM_g]word[SM_h]". For example, the string could also be:
[SM_g]word[SM_h][SM_l]"
or
[SM_g]word[SM_h]"[SM_l].
or
[SM_g]word[SM_h]".
or
[SM_g]word[SM_h][SM_1].
or
[SM_g]word[SM_h].
or simply just
[SM_g]word[SM_h]
These are just some of the examples. The point is that there are three different components (more if you consider the period can also be a comma) that can appear after "[SM_h]word[SM_g]" where these three components can be in any order and sometimes one, two, or all three of the components will be missing.
Not only that, sometimes there will be up to one space before " and the previous component/[SM_g]word[SM_h].
For example:
[SM_g]word[SM_h] ".
or
[SM_g]word[SM_h][SM_l] ".
etc. etc.
I am trying to process this string by moving each of the three components inside of the core string (and preserving the space, in case there is a space before &\quot; and the previous component/[SM_g]word[SM_h]).
For example, [SM_g]word[SM_h].[SM_l]" would turn into
[SM_g]word.[SM_l]"[SM_h]
or
[SM_g]word[SM_h]"[SM_l]. would turn into
[SM_g]word"[SM_l].[SM_h]
or, to simulate having a space before "
[SM_g]word[SM_h] ".
would turn into
[SM_g]word ".[SM_h]
and so on.
I've tried several combinations of regex expressions, and none of them have worked.
Does anyone have advice?
You need to put each component within an alternation in a grouping construct with maximum match try of 3 if it is necessary:
\[SM_g]word(\[SM_h])((?:\.|\[SM_l]| ?"){0,3})
You may replace word with .*? if it is not a constant or specific keyword.
Then in replacement string you should do:
$1$3$2
var re = /(\[SM_g]word)(\[SM_h])((?:\.|\[SM_l]| ?"){0,3})/g;
var str = `[SM_g]word[SM_h][SM_l] ".`;
console.log(str.replace(re, `$1$3$2`));
This seems applicable for your process, in other word, changing sub-string position.
(\[SM_g])([^[]*)(\[SM_h])((?=([,\.])|(\[SM_l])|( ?&\\?quot;)).*)?
Demo,,, in which all sub-strings are captured to each capture group respectively for your post processing.
[SM_g] is captured to group1, word to group2, [SM_h] to group3, and string of all trailing part is to group4, [,\.] to group5, [SM_l] to group6, " ?&\\?quot;" to group7.
Thus, group1~3 are core part, group4 is trailing part for checking if trailing part exists, and group5~7 are sub-parts of group4 for your post processing.
Therefore, you can get easily matched string's position changed output string in the order of what you want by replacing with captured groups like follows.
\1\2\7\3 or $1$2$7$3 etc..
For replacing in Javascript, please refer to this post. JS Regex, how to replace the captured groups only?
But above regex is not sufficiently precise because it may allow any repeatitions of the sub-part of the trailing string, for example, \1\2\3\5\5\5\5 or \1\2\3\6\7\7\7\7\5\5\5, etc..
To avoid this situation, it needs to adopt condition which accepts only the possible combinations of the sub-parts of the trailing string. Please refer to this example. https://regex101.com/r/6aM4Pv/1/ for the possible combinations in the order.
But if the regex adopts the condition of allowing only possible combinations, the regex will be more complicated so I leave the above simplified regex to help you understand about it. Thank you:-)
I am trying to replace some ID numbers in my system to clickable number to open the related record. The problem is, that they are sometimes in this format: 123.456.789.
When I use my regex, I can replace them and it works fine. The problem accurse when I also have IP addresses where the regex also matches: 123.[123.123.123] (the [] indicates where it matches).
How I can I prevent this behavior?
I tried something like this: /^(?!\.)([0-9]{3}\.[0-9]{3}\.[0-9]{3})(?!\.)/
I am working on "notes" in a ticket system. When the note contains only the ID or an IP, the regexp is working. When it contains more text like:
Affected IDs:
641.298.855 (this, lead)
213.794.868
948.895.285
Then it is not matching anymore on my IDs. Could you help me with this issue and explain what I am doing wrong?
Add gm modifier:
/^(?!\.)([0-9]{3}\.[0-9]{3}\.[0-9]{3})(?!\.)/gm
https://regex101.com/r/pK1fV4/2
You don't need to use negative lookahead at the start and also you don't need to include g modifier, just m modifier would be enough for this case because ^ matches the start of a line and the following pattern will match the string which exists only at the start so it won't do any global match (ie, two or more matches in a single line).
/^([0-9]{3}\.[0-9]{3}\.[0-9]{3})(?!\.)/m
For the sake of performance, you further don't need to use capturing group.
/^[0-9]{3}\.[0-9]{3}\.[0-9]{3}(?!\.)/m
While writing an API service for my site, I realized that String.split() won't do it much longer, and decided to try my luck with regular expressions. I have almost done it but I can't find the last bit. Here is what I want to do:
The URL represents a function call:
/api/SECTION/FUNCTION/[PARAMS]
This last part, including the slash, is optional. Some functions display a JSON reply without having to receive any arguments. Example: /api/sounds/getAllSoundpacks prints a list of available sound packs. Though, /api/sounds/getPack/8Bit prints the detailed information.
Here is the expression I have tried:
req.url.match(/\/(.*)\/(.*)\/?(.*)/);
What am I missing to make the last part optional - or capture it in whole?
This will capture everything after FUNCTION/ in your URL, independent of the appearance of any further / after FUNCTION/:
FUNCTION\/(.+)$
The RegExp will not match if there is no part after FUNCTION.
This regex should work by making last slash and part after optional:
/^\/[^/]*\/[^/]*(?:\/.*)?$/
This matches all of these strings:
/api/SECTION/FUNCTION/abc
/api/SECTION
/api/SECTION/
/api/SECTION/FUNCTION
Your pattern /(.*)/(.*)/?(.*) was almost correct, it's just a bit too short - it allows 2 or 3 slashes, but you want to accept anything with 3 or 4 slashes. And if you want to capture the last (optional) slash AND any text behind it as a whole, you simply need to create a group around that section and make it optional:
/.*/.*/.*(?:/.+)?
should do the trick.
Demo. (The pattern looks different because multiline mode is enabled, but it still works. It's also a little "better" because it won't match garbage like "///".)
the url is as this: http://example.com/download/
var pathname = window.location.pathname;
if(pathname=='download/'){
$("#subnav-content div:first").hide();
$("#subnav-content div:second").show();
}
why the above code in jquery doesn't work? i want to when the url is http://example.com/download/. show the secong div.
ps*:does this check affect the site performance?*
You need the leading slash.
'/download/'
If you expect query string parameters you may try a regular expression to just match the download portion of the url: the following matches /download/.
if (window.location.pathname.match(/^\/download\//i))
Regarding the jquery, there is no :second, you need to use :eq(1)
var pathname = window.location.pathname;
if(pathname=='/download/'){
$("#subnav-content div:first").hide();
$("#subnav-content div:eq(1)").show();
}
Response to comments
I'm putting my comment here because the formatting is horrible in the comments. The regular expression for matching download can be summed up as follows:
/ - start of regular expression matching syntax
^ - means start matching at the very start of the screen
\/ - means match the literal string '/', which is a special character which must be escaped
download - match the literal string 'download'
\/ - again means match the literal string '/'
/ - end of the matching syntax
i - regular expression options, i means ignore case
It was not clear to me what your other note was asking for.
Second is not a selector. You want:
$("#subnav-content div:nth-child(2)").show();
Try using
$("#subnav-content div:eq(0)")
$("#subnav-content div:eq(1)")
Also, you need to bind the code to an Event that will get fired when the Document is ready(load, or onDOMReady where supported) otherwise the divs might not exist in memory yet.
ps*:does this check affect the site performance?*
Every line of code has an effect on site performance. Not necessarily a visible one although.
In Jeff Roberson's jQuery Regular Expressions Review he proposes changing the rts regular expression in jQuery's ajax.js from /(\?|&)_=.*?(&|$)/ to /([?&])_=[^&\r\n]*(&?)/. In both versions, what is the purpose of the second capture group? The code does a replacement of the current random timestamp with a new random timestamp:
var ts = jQuery.now();
// try replacing _= if it is there
var ret = s.url.replace(rts, "$1_=" + ts + "$2");
Doesn't it only replace what it matches? I am thinking this does the same:
var ret = s.url.replace(/([?&])_=[^&\r\n]*/, "$1_=" + ts);
Can someone explain the purpose of the second capture group?
It's to pick up the next delimiter in the query string on the URL, so that it still works properly as a query string. Thus if the url is
http://foo.bar/what/ever?blah=blah&_=12345&zebra=banana
then the second group picks up the "&" before "zebra".
That's an awesome blog post by the way and everybody should read it.
edit — now that I think about it, I'm not sure why it's necessary to bother with replacing that second delimiter. In the "fixed" expression, that greedy * will pick up the whole parameter value and stop at the delimiter (or the end of the string) anyway.
I think you're right. It was needed in the original because matching the ampersand or end-of-string was how the .*? knew when to stop. In Jeff's version that's no longer necessary.
As the author of the article I can't tell you the reason for the second capture group. My intent with the article was to take existing regexes and simply make them more efficient - i.e. they should all match the same text - just do it faster. Unfortunately I did not have time to delve deeply into the code to see exactly how each and every one of them was being used. I assumed that the capture group for this one was there for a reason so I did not mess with it.