Regex for ASP.NET url rewrite - asp.net

Sample text =
legacycard.ashx?save=false&iNo=3&No=555
Sample pattern =
^legacycard.ashx(.*)No=(\d+)
Want to grab group #2 value of "555" (the value of "No=" in the sample text)
In Expresso, this works, but in ASP.NET UrlRewrite, it is not catching.
Am I missing something?
Thanks!

I would do something along these lines:
^legacycard.ashx\?(?:.+&)*No=(\d+)
The \? will escape the question mark that normally separates the URL and the parameters, then you make sure that it will capture every parameter key/value pair (anything that ends on &) before the parameter you actually care about. Using ?: lets you specify that the set of brackets is non capturing (I'm assuming you won't need any of the data, has the potential to slightly speeds up your regex) and leaves you just 555 captured. The added benefit of this approach is that it'll work regardless of parameter order.

Just use this regex:
^legacycard\.ashx\?save=(false|true)&iNo=(?<ino>\d+)&No=(?<no>\d+)
Then Regex Replace with
${no}

Looks fine to me, your regex should match the entire string
legacycard.ashx?save=false&iNo=3&No=555
not sure why you have groups, but groups should also return
?save=false&iNo=3&
and
555
For good measure you should know that the . in legacycard.ashx is also interpreted by regex and you would normally escape it, in this case it dosen't matter because a single dot matches everything, also a dot. :)

Try this
^legacycard.ashx(\?No=|.*?&No=)(\d+)
this should work.

Related

Regex to match for multiple strings anywhere within a string

I'm trying to add some validation in ASP.NET using Regex. Essentially I need to ensure a text box includes both ***ThisString*** and ***ThatString*** including the asterisks.
I can get it to work with one, or one or the other, just not both being present at the same time and at any part of the string.l it's validating.
Thanks
As nanhydrin correctly pointed out, my solution will not work if there are multiple of one of the strings but not the other. If that case may occur, you can check for each string separately for readability's sake
First regular expression- (?:\*{3}ThisString\*{3})
Second regular expression- (?:\*{3}ThatString\*{3})
If matches are found in both cases, you're good to go!
Original Answer:-
This is the regular expression you want: (?:\*{3}(?:ThisString|ThatString)\*{3})
Note: Make sure to have global match on and be sure to escape the asterisks correctly.
If the above expression finds 2 (or more) matches, it means you're good to go.
Explanation:-
The entire thing is in a non capturing group, this is to ensure, everything within does get matched fully
There are 3 stars on each side of the strings, having 3 stars on one side but not the other will not result in a match
Both ThisString and ThatString are in a grouped alternative, this is to reduce clutter, you could totally jam every possible positional pattern but this is just better as position doesn't matter here. ***ThatString*** can come before ***ThisString*** or vice versa.
MAKE SURE to check the length of the matches found, the length must be 2 for your
described condition to be satisfied.
Here's the live demo
Using #Chase's answer I was able to come up with the following:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
Regex thisString = new Regex("(?:\*{3}ThisString\*{3})");
Regex thatString = new Regex("(?:\*{3}ThatString\*{3})");
if (!thisString.IsMatch(value.ToString()) || !thatString.IsMatch(value.ToString()))
{
return new ValidationResult("***ThisString*** and ***ThatString*** are used to generate the email text. Please ensure the text above has both ***ThisString*** and ***ThatString*** somewhere within the text."); }
return ValidationResult.Success;
}
Now if either regex patterns don't match anywhere, it'll return an error.

How to write a regex OR statement within strapply in R

I have been using strapplyc in R to select different portions of a string that match one particular set of criteria. These have worked successfully until I found a portion of the string where the required portion could be defined one of two ways.
Here is an example of the string which is liberally sprinkled with \t:
\t\t\tsome words here\t\t\tDefect: some more words here Action: more words
I can write the strapply statement to capture the text between Defect: and the start of Action:
strapplyc(record[i], "Defect:(.*?)Action")
This works and selects the chosen text between Defect: and Action. In some cases there is no action section to the string and I've used the following code to capture these cases.
strapplyc(record[i], "Defect:(.*?)$")
What I have been trying to do is capture the text that either ends with Action, or with the end of the string (using $).
This is the bit that keeps failing. It returns nothing for either option. Here is my failing code:
strapplyc(record[i], "Defect:(.*?)Action|$")
Any idea where I'm going wrong, or a better solution would be much appreciated.
If you are up for a more efficient solution, you could drop the .*? matching and unroll your pattern like:
Defect:((?:[^A]+|A(?!ction))*)
This matches Defect: followed by any amount of characters that are not an A or are an A and not followed by ction. This avoids the expanding that is needed for the lazy dot matching. It will work for both ways, as it does stop matching when it hits Action or the end of your string.
As suggested by Wiktor, you can also use
Defect:([^A]*(?:A(?!ction)[^A]*)*)
Which is a little bit faster when there are many As in the string.
You might want to consider to use A(?!ction:) or A(?!ction\s*:), to avoid false early matches.
The alternation operator | is the regex operator with the lowest precedence. That means the regex Defect:(.*?)Action|$ is actually a combination of Defect:(.*?)Action and $ - since an empty string is a valid match for $, your regex returns the empty string.
To solve that, you should combine the regexes Defect:(.*?)Action and Defect:(.*?)$ with an OR:
Defect:(.*?)Action|Defect:(.*?)$
Or you can enclose Action|$ in a group as Sebastian Proske said in the comments:
Defect:(.*?)(?:Action|$)

regex to match page[0-9] and nothing before or after

I have a regex but it's not quite working the way i want
page[0-9]*
/pages/search.aspx?pageno=3&pg=232323&hdhdhd/page73733/xyz
In the above example, the only thing I want to match is page73733. But my regex matches the page in /pages and it matches page in pageno=3
i also tried page[0-9].*, then it matches page73733 but it also matches everything that comes after it so that it actually matches page73733/xyz
page[0-9].*[^a-zA-Z&?/=]
That seems to do what i want, but that also seems like a ugly way to do it. Plus if i had something like /page123/xyz/page456 it'll match that whole string.
So is there a better way to do this? I want to match ONLY the string page when it is followed by any number of digits, and if anything comes after the digits it should stop.
* means 0 or more occurrences. + means 1 or more occurrences.
page[0-9]+ should work.
page[0-9]*
Will match page followed by zero or more numbers. What you want is:
page[0-9]+
Which will match page followed by one or more numbers.
You almost got it. Just use + instead of * as that will force a match that has numbers after it.
Another way to type that expression would be
/page[0-9]+
note the / , this would be helpful because without it you might get a match with something like "notApage123"
The regex page[0-9]* will match [0-9] 0 or more times. + would match it 1 or more times, and ? would match it 0 or 1 times. An equivalent method to ?+* is as follows:
?={0,1}
*={0,}
+={1,}
This may be helpful for if you wanted to match a date:\\d{4}(-\\d{1,2}){2} which would match 2013-5-31
-
That said, the resulting Regex for your particular problem would be:
page\\d+
page\\d{1,}
page[0-9]+
or page[0-9]{1,}
In your example "/page123/xyz/page456" you may want to match all occurrences, so don't forget the g or global modifier.
If I understand your problem correctly, you only need to add $ to your original regex to specify that after page you want the string to end. So the regex would be
page[0-9]*$
Also, this will match strings that end in page too, if you want only strings that end in page followed by any number, use this regex
page[0-9]+$

Rewriting a URL with RegEx

I have a RegEx problem. Consider the following URL:
http://ab.cdefgh.com/aa-BB/index.aspx
I need a regular expression that looks at "aa-BB" and, if it doesn't
match a number of specific values, say:
rr-GG
vv-VV
yy-YY
zz-ZZ
then the URL should redirect to some place. For example:
http://ab.cdefgh.com/notfound.aspx
In web.config I have urlrewrite rules. I need to know what
the regex would be between the tags.
<urlrewrites>
<rule>
<url>?</url>
<rewrite>http://ab.cdefgh.com/notfound.aspx</rewrite>
</rule>
</urlrewrites>
Assuming you don't care about the potential for the replacement pattern to be in the domain name or some other level of the directory structure, this should select on the pattern you're interested in:
http:\/\/ab\.cdefgh\.com\/(?:aa\-BB|rr\-GG|vv\-VV|yy\-YY|zz\-ZZ)\/index\.aspx
where the aa-BB, etc. patterns are simply "or"ed together using the | operator.
To further break this apart, all of the /, ., and - characters need to be escaped with a \ to prevent the regex from interpreting them as syntax. The (?: notation means to group the things being "or"ed without storing it in a backreference variable (this makes it more efficient if you don't care about retaining the value selected).
Here is a link to a demonstration (maybe this can help you play around with the regex here to get to exactly which character combinations you want)
http://rubular.com/r/UfB65UyYrj
Will this help?
^([a-z])\1-([A-Z])\2.*
It matches:
uu-FF/
aa-BB/
bb-CC/index
But not
aaBB
asdf
ba-BB
aA-BB
(Edit based on comment)
Just pipe delimit your desired urls inside of () and escaping special chars.
Eg.
^(xx-YY|yy-ZZ|aa-BB|goodStuff)/.*
But, I think you might actually want the following which matches anything other than the urls that you specify, so that all else goes to notfound.aspx:
^[^(xx-YY|yy-ZZ|aa-BB|goodStuff)]/.*
Assuming you want anything but xx-XX, yy-YY and zz-ZZ to redirect:
[^(xx\-XX)|(yy\-YY)|(zz\-ZZ)]

Don't want spaces in the text, but this regex is passing not sure why

I am using the following regex
/[a-zA-Z0-9]+/i.test(value)
If I enter a space in the word, it passes.
I don't see where spaces are aloud in the regex, why is it passing?
You need to set the beginning and end bounderies so that the entire string must match the regular expression, otherwise it'll look for any match (which in this case is one or more of the characters specified).
Try this:
/^[a-zA-Z0-9]+$/i.test(value)
Because you haven't anchored it.
For these sorts of tests, it's typically safer to make sure you don't have the negated character class:
/[^a-zA-Z0-9]/

Resources