I am trying to search and replace in VSCode in all the xml files. I am interested in the below line in all the files which has name "somekey"
<setting name="somekey" value="abc-def.google.xyz.com" />
<setting name="somekey" value="abc-xyz.google.xyz.com" />
I am trying to convert this line to
<setting name="somekey" value="abc-def-ghi.google.xyz.com" />
<setting name="somekey" value="abc-xyz-ghi.google.xyz.com" />
so far I have this
(<setting name="somekey" value="abc-)((.|n)*?.google.xyz.com). How do I make it so the group 1 includes everything until the first ".". Any pointers?
https://regex101.com/r/WeEkgQ/1
You can move the part matching until .google.xyz.com to the first group, and in the replacement use the 2 capture groups $1.ghi$2
To match the dot literally you have to escape it \. and note that the current pattern is not matching the closing />
(<setting name="somekey" value="abc-.*?)(\.google\.xyz\.com")
Regex demo
Note that this part (.|n) matches either any char or a n char. If you meant to use (.|\n) you could use [\s\S\r]+? instead of using the alternation to match over multiple lines making it a bit more efficient.
Related
I've searched several SO posts and haven't found what I'm looking for. It might exists but might be fairly old enough to not show up for me. I found a post (Nginx rewrite: add trailing slash, preserve anchors and query strings) so close to what I need, but it's regex solution does not work for URL Rewrite for IIS, unless I'm doing it wrong.
Problem
I'm trying to add a forward slash / to the end of my url paths while also preserving any existing for query strings ? and anchors #.
Desired Solution
Basically, here's the desired results to each problem:
Entry: https://my.site.com/about
Result: https://my.site.com/about/
Entry: https://my.site.com/about?query=string
Result: https://my.site.com/about/?query=string
Entry: https://my.site.com/about#TestAnchor
Result: https://my.site.com/about/#TestAnchor
Entry: https://my.site.com/about?query=string#TestAnchor
Result: https://my.site.com/about/?query=string#TestAnchor
Current Tests
Our current regex ignores query strings and anchors, but I would like to take them into consideration now.
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^.?]+[^.?/])$" />
<action type="Redirect" url="{R:1}/" redirectType="Permanent" />
</rule>
I've also tested another regex but it only works if the url contains both a query string AND an anchor.
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^(.*)(\?.*?)(\#.*?)$" />
<action type="Redirect" url="{R:1}/{R:2}{R:3}" redirectType="Permanent" />
</rule>
NOTE: I just tested this last one (^(.*)(\?.*?)(\#.*?)$) and it actually doesn't work. If the url already contains a / before the ? the test passes which it should not, so I have more work to do here.
Question
Is there a single regex that I can use to solve this or do I need to use multiple rules?
TL;DR
IIS Rewrite (ALL) URIs with Trailing Slash & preserve Fragment and Query Strings
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)" />
<action type="Redirect" url="{R:1}/{R:2}" redirectType="Permanent" />
</rule>
IIS use ECMAScript so you can Try it here : https://regexr.com/6ele7
Update
IIS Rewrite (Considered) URIs with Trailing Slash & preserve Fragment and Query Strings
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^/]+:\/\/[^/#?]+|[^?#]+\/[^/.?#]+)([?#].*)?$" />
<action type="Redirect" url="{R:1}/{R:2}" redirectType="Permanent" />
</rule>
Try it here : https://regexr.com/6fk3g
http://127.0.0.1 --> http://127.0.0.1/
https://localhost --> https://localhost/
https://localhost? --> https://localhost/?
https://localhost/ --> https://localhost/
https://my.site.com --> https://my.site.com/
https://my.site.com:443? --> https://my.site.com:443/?
https://my.site.com/ --> https://my.site.com/
https://my.site.com/about.php --> https://my.site.com/about.php
https://my.site.com/about.php? --> https://my.site.com/about.php?
https://my.site.com/about --> https://my.site.com/about/
https://my.site.com/about? --> https://my.site.com/about/?
https://my.site.com/about/ --> https://my.site.com/about/
https://my.site.com/about/? --> https://my.site.com/about/?
https://my.site.com/about?query --> https://my.site.com/about/?query
https://my.site.com/about/?query --> https://my.site.com/about/?query
https://my.site.com/about.php?query --> https://my.site.com/about.php?query
https://my.site.com/about#hash --> https://my.site.com/about/#hash
https://my.site.com/about/#hash --> https://my.site.com/about/#hash
https://my.site.com/about.php#hash --> https://my.site.com/about.php#hash
https://my.site.com/about?query#hash --> https://my.site.com/about/?query#hash
https://my.site.com/about/?query#hash --> https://my.site.com/about/?query#hash
https://my.site.com/folder.name/about?query --> https://my.site.com/folder.name/about/?query
https://my.site.com/about?query#hash:http://test.com?q --> https://my.site.com/about/?query#hash:http://test.com?q
Explaination (All)
Level 1 - Lets just think about your examples:
^([^?#]+?)\/?([?#].*)?$
Group #1: ^ In first, [^?#] Any character except ?/#, Go much but lazy +? (Stop on first possible, by looking to next)
Ignore: \/? Then if a / exist or not
Group #2: [?#] = ?/# And .* Any much character next to that till $ End, (...)? If exist
It work well. But it will deal not right with:
https://my.site.com/about.php?query --> https://my.site.com/about.php/?query !!!
So let's add an exception...
Level 2 - How if we take possible file name Name.name.name.ext as Group #2?
^([^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?)$
(?:...) Non-Capturing group
([^/?#]+\.[^/?#]+)? Look for any possible file name or (?:[?#].*)? Any possible query or anchor strings
Now everything is OK, except this:
https://my.site.com? --> https://my.site.com? !!!
So we need another exception in Group #1
Level 3 - Take just domain URI as an alternative
^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)
(...|...) Alternative
[^/]+:\/\/[^/#?]+ First check if (not lazy) any pattern like ...://... till not / # ? exist?
Now it work great!
+ Explaination (Considered)
Level 4 - How if we just add a Not-Accepting . & / character set in first group to just match considered URIs and ignore others?
^([^/]+:\/\/[^/#?]+|[^?#]+\/[^/.?#]+)([?#].*)?$
\/[^/.?#]+ Check if after last / the set of characters be not /.?#
Now it is even smaller and faster!
Analyzing other method
As #károly-szabó answered well here, instead of looking for Not-Accepted character sets, we can look for matched pattern.
So if we want to use the method but in simpler way (2 Groups) (+ Some minor optimization), the regex will be:
^(https?:\/\/[\w.:-]+\/?(?:[\w.-]+\/)*[\w-]+(?!\/))([?#].*)?$
But URI path Accepted characters are more.
So a wider version of that Regex can be:
^(https?:\/\/[\w.:-]+\/?(?:[\w!#-)+-.;=#~]+\/)*[\w!#-);=#~+,-]+(?!\/))([?#].*)?$
Try it here: https://regexr.com/6elea
Note: Still "multibyte Unicode as domain name is allowed" but i ignored that in this method.
P.S.
Actually i don't think that we should rewrite it on IIS, because of these reasons:
Anchors char # can be part of a folder name (by %23)
A file name can have no extension
IIS/Browsers usually will (/should) handle Anchors/Queries
Ref:
IIS: UrlRewrite middleware query strings are preserved
Google/Anchor tags are stripped from URLs
RFC URI References
URI Wiki
How does IIS URL Rewrite handle # anchor tags
I Mean:
https://my.site.com/ --> (=Call root)
https://my.site.com/about --> (=Call root > Folder/File name about)
https://my.site.com/about/ --> (=Call root > Folder name about)
https://my.site.com/about?query --> (=Call root > Folder/File name about + Query)
https://my.site.com/about/?query --> (=Call root > Folder name about + Query)
https://my.site.com/about.php?query --> (=Call root > File name about.php + Query)
[When browser strip it:]
https://my.site.com/about#hash --> (=Call root > Folder/File name about + Anchor)
https://my.site.com/about/#hash --> (=Call root > Folder name about + Anchor)
https://my.site.com/about.php#hash --> (=Call root > File name about.php + Anchor)
[If not?]
https://my.site.com/folder#name/?query#hash
https://my.site.com/folder.name/about.php?query=one/two
You can try with this regex https://regex101.com/r/6TSqaP/2. This is matching every provided example and solves the problem if the url already has an ending '/'.
^((?:https?:\/\/[\w\.\-]*)(?:[\w\-]+\/)*(?:[\w\-]+)(?!\/))(\?.*?)?(\#.*?)?$
I used your second example as base for my regex, with the following logic.
The parts of the url: scheme://authority/path?query#fragment
first capture group matches the scheme://authority/path part of the url
second capture group optional and matching the ?query
third capture group also optional and for the #fragment
regex explanation
^( # should start with this
(?:https?:\/\/[\w\.\-]*) # match the http or https protocol and the domain
(?:[\w\-]+\/)* # match the path except the last element of it (optional)
(?:[\w\-]+)(?!\/) # match the last path element, but only if it's not closed with '/'
) # {R:1}
(\?.*?)? # {R:2} query (optional)
(\#.*?)? # {R:3} fragment (optional)
$ # string should end
Nginx
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^((?:https?:\/\/[\w\.\-]*)(?:[\w\-]+\/)*(?:[\w\-]+)(?!\/))(\?.*?)?(\#.*?)?$" />
<action type="Redirect" url="{R:1}/{R:2}{R:3}" redirectType="Permanent" />
</rule>
Edit: Updated regex to handle dashes (-) and multiple path elements
I have a string with a version as .v_september (every month it will vary). In this i wanted to take the value after underscore, which means "sep" (First 3 letters alone).
By using the regex .v_(.*) i am able to take the complete month and not able to get the first 3 letters alone.
Can someone help me out how can I achieve this in Apache ANT.
Thanks !
Regex functions on properties are a bit awkward in native Ant (as opposed to working with text within files). Ant-contrib has the replaceregexp task, but I try to avoid ant-contrib whenever possible.
Instead, it can be accomplished with the loadfile task and a nested filter:
<property name="version" value=".v_september" />
<loadfile property="version.month.short">
<propertyresource name="version" />
<filterchain>
<tokenfilter>
<replaceregex pattern="\.v_(.{3}).*" replace="\1" />
</tokenfilter>
</filterchain>
</loadfile>
<echo message="${version.month.short}" />
Regarding the regex pattern, note how it needs to end with .*. This is because Ant doesn't have a "match" function that simply returns the content of a capture group. It's just running a replacement, so we need to replace everything in the string that isn't part of the group.
.* will capture everything and for limiting to capturing only three characters you need to write {3} instead of *. Also you should escape the . in the beginning of your regex to only match a literal dot. You can use this regex and capture from group1,
\.v_(.{3})
Demo
I have regex that accepts all the mobile user agents. But I want to negate this regex so that it accepts all possible desktop browsers.
<add input="{HTTP_USER_AGENT}" pattern="(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino" />
<add input="{HTTP_USER_AGENT}" pattern="^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)" />
Can anybody provide the solution for the same ?
Some (few) regex flavors allow to use variable length lookaheads (.net for example).
If you have such one, you can use
^(?!.*(?:pattern)).*$
for your first pattern (it tests for occurences anywhere in the string), and
^(?!pattern)
for the second one (you can remove ^ from pattern there).
Your second pattern does not contain any variable length content - thus it should work in every regex flavor allowing to use negative lookaheads (?!...)
I'd like to build a IIS url rewrite rule that matches several file extensions but ignore the query string.
Samples:
/hello.html // Match
/test?qs=world.html // Should not match
/test?qs=world.html&qs2=x // Should not match
Here is what I was using that does not work correctly:
<add matchType="Pattern" input="{HTTP_URL}" pattern=".+\.(js|css|less|html|eot|svg|ttf|woff|json|xml)$" negate="true" /> <!--Any url with a dot for file extension-->
Use \w+ instead of .+ .................(\w is equivalent to [a-zA-Z0-9_]):
<add matchType="Pattern" input="{HTTP_URL}" pattern="\w+\.(js|css|less|html|eot|svg|ttf|woff|json|xml)$" negate="true" /> <!--Any url with a dot for file extension-->
If you want to allow other characters (non included in \w) and still ignore query string you can use [^?]+ instead of .+
see if this works for you:
I write it in javascript, (I don't know IIS) but the regex is always similar
/^.*\/[\w]+\.[\w]{2,4}$/.test('/test?qs=world.html') // return false
/^.*\/[\w]+\.[\w]{2,4}$/.test('/world.html') // return true
maybe it work as:
<add matchType="Pattern" input="{HTTP_URL}" pattern="^.*\/[\w]+\.[\w]{2,4}$" negate="true" />
but I put the extension as a generic way. if you want to make a whitebox test for extension, you may replace it to:
^.*\/[\w]+\.(js|css|less|html|eot|svg|ttf|woff|json|xml)$
I assume this will work in IIS: ^[^?]*$ will match any string not containing a ?.
I need to replace different values of receiveTimeOut attribute with a receiveTimeOut="59:59:59"
Can wild card search be used to achieve this task, in Visual Studio?
<endpoint receiveTimeOut="10:10:20" someOtherProperty="x1" yetAnotherProperty="y1" />
<endpoint receiveTimeOut="10:50:20" someOtherProperty="x2" yetAnotherProperty="y2" />
...
<endpoint receiveTimeOut="30:50:20" someOtherProperty="x3" yetAnotherProperty="y3" />
I tried: using wildcard option in Find & Replace dialog, receiveTimeOut="*" but this selects complete line, receiveTimeOut="10:10:20" someOtherProperty="x1" yetAnotherProperty="y1" />
As you might have guessed, I am editing WCF service web.config and have to do this task manually & repeatedly.
Using the regex option...
Find: <endpoint receiveTimeOut="[^"]+"
Then...
Replace: <endpoint receiveTimeOut="59:59:59"
The [^"]+ part uses a negative character class that matches any character except for a double quote. The + will match it one or more times.
It turns out that this is actually quite simple to do with a regular expression.
Just use .* for your wildcard and check Use regular expressions.
For example, I have some grids and I want to find columns with an attribute of Visible="False" so a string might be:
telerik:GridBoundColumn name="name" Visible="False"
My search string would be: "GridBoundColumn.*Visible="False""
Done.
Ahmad's is the way to go. But as a naive and bit different alternative, one could search:
receiveTimeOut="[0-9]*\:[0-9]*\:[0-9]*"
This requires the data between the double quotes of the receiveTimeOut value has two colons (which are escaped) with any number of digits about them.