I need to validate a regex where between STRING_{here}G_ can be 0 or even 4 digits, I tried the following regex:
(?<=TEST_[0-9]{0,4}G_).*
But the tester returns the error:
Your pattern contains one or more errors, please see the explanation section above.
And when trying to use manually, using two [0-9], it doesn't get my strings
ABC_TEST_20G_a123-abc1
ABC_TEST_100G_abc1
I need a regex that validates both strings and returns what is after G_
Remembering that the regex must have the "TEST_", it is a string that I need to validate
Most regexp engines don't allow lookbehinds to be variable-length, so you can't have a {0,4} quantifier in it.
Instead of a lookbehind, use a capture group to capture everything after this pattern.
TEST_[0-9]{0,4}G_(.*)
Capture group 1 will contain what you want to get.
DEMO
Related
I have a string. An example might be "Contact /u/someone on reddit, or visit /r/subreddit or /r/subreddit2"
I want to replace any instance of "/r/x" and "/u/x" with "[/r/x](http://reddit.com/r/x)" and "[/u/x](http://reddit.com/u/x)" basically.
So I'm not sure how to 1) find "/r/" and then expand that to the rest of the word (until there's a space), then 2) take that full "/r/x" and replace with my pattern, and most importantly 3) do this for all "/r/" and "/u/" matches in a single go...
The only way I know to do this would be to write a function to walk the string, character by character, until I found "/", then look for "r" and "/" to follow; then keep going until I found a space. That would give me the beginning and ending characters, so I could do a string replacement; then calculate the new end point, and continue walking the string.
This feels... dumb. I have a feeling there's a relatively simple way to do this, and I just don't know how to google to get all the relevant parts.
A simple preg_replace will do what you want.
Try:
$string = preg_replace('#(/(?:u|r)/[a-zA-Z0-9_-]+)#', '[\1](http://reddit.com\1)', $string);
Here is an example: http://ideone.com/dvz2zB
You should see if you can discover what characters are valid in a Reddit name or in a Reddit username and modify the [a-zA-Z0-9_-] charset accordingly.
You are looking for a regular expression.
A basic pattern starts out as a fixed string. /u/ or /r/ which would match those exactly. This can be simplified to match one or another with /(?:u|r)/ which would match the same as those two patterns. Next you would want to match everything from that point up to a space. You would use a negative character group [^ ] which will match any character that is not a space, and apply a modifier, *, to match as many characters as possible that match that group. /(?:u|r)/[^ ]*
You can take that pattern further and add a lookbehind, (?<= ) to ensure your match is preceded by a space so you're not matching a partial which results in (?<= )/(?:u|r)/[^ ]*. You wrap all of that to make a capturing group ((?<= )/(?:u|r)/[^ ]*). This will capture the contents within the parenthesis to allow for a replacement pattern. You can express your chosen replacement using the \1 reference to the first captured group as [\1](http://reddit.com\1).
In php you would pass the matching pattern, replacement pattern, and subject string to the preg_replace function.
In my opinion regex would be an overkill for such a simple operation. If you just want to replace instance of "/r/x" with "[r/x](http://reddit.com/r/x)" and "/u/x" with "[/u/x](http://reddit.com/u/x)" you should use str_replace although with preg_replace it'll lessen the code.
str_replace("/r/x","[/r/x](http://reddit.com/r/x)","whatever_string");
use regex for intricate search string and replace. you can also use http://www.jslab.dk/tools.regex.php regular expression generator if you have something complex to capture in the string.
I am using PHP Regex to see if a pattern is in my string. Simply put, I want one of two words followed by a number. So, here's my pattern:
#(guitare|piano)[0-9]#
Basically, if the string contains the word "guitare", I don't want it to be matched, only if I have "guitare9" or "piano0"
At this point, If I use this pattern for the follwing string:
J'aime la guitare9
The array of the preg_match() returns guitare and guitare9: http://www.phpliveregex.com/p/7tZ
What do I have to change in my regex to only match guitare9 ?
Turn capturing group in your regex to non-capturing group. Because preg_match would display the match and also the captured strings in an array. By turning capturing group into non-capturing, you must get a single array element.
#(?:guitare|piano)[0-9]#
DEMO
I have an html form with an input for a sales order number which should have the format of K1234/5678. It should always start with the letter K then 4 numbers, a / and followed by another set of 4 numbers.
I'm trying to validate the formatting using preg_match and I'm getting lost in the syntax of preg_match. From http://php.net/manual/en/function.preg-match.php I've gotten close. With the following code I'm able to verify that it contains at least 1 letter, some numbers and at least 1 non- alphanumeric value.
$so= $_POST['so'];
if (preg_match(""/^(?=.*[a-z]{1})(?=.*[0-9]{4})(?=.*[^a-z0-9]{1})/i", $so))
{
print $so;
}
What is the correct syntax to use for this? Is preg_match even the best way to do this?
Try this:
preg_match("#^K[0-9]{4}/[0-9]{4}$#i", $so)
Explanation:
The # characters are regular expression delimiters - they indicate the start/end of the pattern. The ^ and $ indicate the start and end of the string - this means that it will only match if your sales order number is the only thing in the string. The letter K means match that letter, [0-9]{4} means match a digit exactly 4 times. The i at the end means a case-insensitive match - the K will match either "K" or "k".
When developing regular expressions, I often use regular expression testers - these allow you to enter your data and try a bunch of different things to refine your regex. Google PHP regex tester to find a list of tools. Also, there's a very complete reference to regular expressions at http://www.regular-expressions.info/.
I need to match text which has #, #, and any number in it. The characters can be in random position as long as they are in the text. Given this input:
abc##d9
a9b#c#d
##abc#9
abc9d##
a#b#c#d
The regex should match the first 3 lines. Currently my regex is:
/#.*?#.*?[0-9]/
Which doesn't work since it will only match the three chars in sequence. How to match the three chars in random order?
Found one of this ugly regex, if you really must use one:
/(?=.*#)(?=.*#)(?=.*[0-9]).*/
http://jsfiddle.net/BP53f/2/
The regex is basically using what they call lookahead
http://www.regular-expressions.info/lookaround.html
A simple case from the link above is trying to match q, followed by u, by doing q(?=u), that's why it's called lookahead, it finds q followed by u ahead.
Let's take one of your valid case: a9b#c#d
The first lookahead is (?=.*#), which states: Match anything, followed by a #. So it does, which is the string a9b#c, then since the match from the lookahead must be discarded, the engine steps back to the start of the string, which is an a. Then it goes to
(?=.*#), which states: Match anything that is followed by #, then it finds it at a9b. etc. The difference between using lookahead and (a)(b)(c) is basically the stepping back.
From the link above:
Let's take one more look inside, to make sure you understand the
implications of the lookahead. Let's apply q(?=u)i to quit. I have
made the lookahead positive, and put a token after it. Again, q
matches q and u matches u. Again, the match from the lookahead must be
discarded, so the engine steps back from i in the string to u. The
lookahead was successful, so the engine continues with i. But i cannot
match u. So this match attempt fails. All remaining attempts will fail
as well, because there are no more q's in the string.
It is ugly because it's difficult to maintain... You basically have 3 different sub-regex inside the brackets.
Use separate expressions to make sure # and # are present. Once they are, remove them and match for the rest of the characters/digits.
Decided I better write this as an answer:
$text = "a9b#c#d";
$themAll = "##";
$themAny = "0123456789";
echo (strspn($themAll, $text)==strlen($themAll) && strpbrk($text, $themAny));
For maintenance and some (limited) extending this should be as easy as it gets, especially whth longer $themAll lists.
I have to create regex to match ugly abbreviations and numbers. These can be one of following "formats":
1) [any alphabet char length of 1 char][0-9]
2) [double][whitespace][2-3 length of any alphabet char]
I tried to match double:
preg_match("/^-?(?:\d+|\d*\.\d+)$/", $source, $matches);
But I coldn't get it to select following example: 1.1 AA My test title. What is wrong with my regex and how can I add those others to my regex too?
In your regex you say "start of string, followed by maybe a - followed by at least one digit or followed by 0 or more digits, followed by a dot and followed by at least one digit and followed by the end of string.
So you regex could match for example.. 4.5, -.1 etc. This is exactly what you tell it to do.
You test input string does not match since there are other characters present after the number 1.1 and even if it somehow magically matched your "double" matching regex is wrong.
For a double without scientific notation you usually use this regex :
[-+]?\b[0-9]+(\.[0-9]+)?\b
Now that we have this out of our way we need a whitespace \s and
[2-3 length of alphabet]
Now I have no idea what [2-3 length of alphabet] means but by combining the above you get a regex like this :
[-+]?\b[0-9]+(\.[0-9]+)?\b\s[2-3 length of alphabet]
You can also place anchors ^$ if you want the string to match entirely :
^[-+]?\b[0-9]+(\.[0-9]+)?\b\s[2-3 length of alphabet]$
Feel free to ask if you are stuck! :)
I see multiple issues with your regex:
You try to match the whole string (as a number) by the anchors: ^ at the beginning and $ at the end. If you don't want that, remove those.
The number group is non-catching. It will be checked for matches, but those won't be added to $matches. That's because of the ?: internal options you set in (?:...). Remove ?: to make that group catching.
You place the shorter digit-pattern before the longer one. If you swap the order, the regex engine will look for it first and on success prefer it over the shorter one.
Maybe this already solves your issue:
preg_match("/-?(\d*\.\d+|\d+)/", $source, $matches);
Demo