tags. And by "content", let's say we're talking
about sequences of word and whitespace characters.
Using our recipe, we can translate the assignment like so:
[^<]*|([\w\s]+)
As a reminder (see the lookout section for details), it would not do
to use a (.*) in the GetThis section, because at any point in the
string prior to a bolded section, the exclusion rule would fail,
while the naughty dot-star would swallow the entire string from that
point to the end--including any bolded sections.
In that case, how about the lazy quantifier (.*?), you might wonder?
You could do that--but make sure to see the section explaining why
lazy quantifiers are expensive on the Mastering Quantifiers page.
Back the the article's Table of Contents
A Variation: Deleting the Matches
Sometimes, you want to match content in order to delete it. In this
case, there is a simple tweak to our usual recipe that allows us to
delete the matches directly without inspecting Group 1 captures. To
search, instead of our usual recipe:
NotThis|NotThat|GoAway|(WeWantThis)
We use:
(KeepThis|KeepThat|KeepTheOther)|DeleteThis
As you can see, the location of the parentheses has been inverted. We
can now replace the match with Group 1. There are two cases:
- If the match took place on the left branch of the alternation, and
therefore captured to Group 1, the match is replaced with itself (no
change);
- If the match took place on the right side of the alternation, the
match is replaced with Group 1, which is empty: it is therefore
deleted.
Here is an interesting variation to do the same:
(KeepThis)|(KeepThat)|(KeepTheOther)|DeleteThis
For the replacement, we concatenate Groups 1, 2 and 3 (in any order).
Since only one of those groups is ever captured (if any), the other
two groups contain empty strings. Once again, the match is replaced
with itself (if captured) or with an empty string.
There is no standard for replacement syntax, so in one language this
may look like \1\2\3, $1$2$3 or m.group(1) + m.group(2) + m.group(3).
Variation for Perl, PCRE and Python: (*SKIP)(*FAIL)
Perl, PCRE (C, PHP, R...) and Python's alternate regex engine have a
variation that uses almost entirely the same syntax, but that returns
the desired matches as the overall match instead of returning them in
capture Group 1. In these flavors, this is a neat trick to know as it
can save us one or two lines of code.
Remember that in our technique, when we express a series of unwanted
contexts in alternations to be matched and thrown in the garbage bin,
such as NotThis|NotThat, the key to success is that when such
undesirable areas of the strings are matched, they are in effect
SKIPPED. After matching them, the engine attempts the next match
starting at the position immediately following the preceding match.
The entire area to be excluded has been gobbled up, and therefore
skipped.
Well, with Perl, PCRE and Python's alternate regex engine, you can
use a construct that makes the engine to match that undesirable
content, then fail the match... after which the engine skips the entire
substring that just failed and starts the next match attempt at the
position immediately following the bad string. This allows us to do
the same as we've been doing, but we no longer need parentheses to
capture the content we want because there is no longer a garbage bin
full of unwanted matches to be ignored. We can inspect the matches
directly, because the pattern only matches what we want.
That syntax can either be written as (*SKIP)(*FAIL), (*SKIP)(*F) or
(*SKIP)(?!). That's because (*FAIL) and (*F) are both synonyms for
(?!), which, as we saw on the tricks page, is an expression that
never matches, forcing the engine to backtrack in search of a
different match.
As for (*SKIP), it's a backtracking control verb in Perl, PCRE and
Python's alternate regex engine. You can read all about it on my page
about backtracking control verbs. When the engine tries to backtrack
across (*SKIP), the match attempt explodes. Instead of starting the
next match attempt at the next starting position in the string, the
engine advances to the string position corresponding to where (*SKIP)
was encountered. This means that anything to the left of (*SKIP) is
never visited again. Apart from time-saving benefits, this technique
allows us to reject entire chunks of text in one go.
Remember the overall recipe to avoid context X? It was
Not_X|(GetThis)
Using Perl, PCRE (PHP, R, C...) or Python's alternate regex engine, we
can accomplish the same with either of these:
Not_A(*SKIP)(*FAIL)|GetThis Not_A(*SKIP)(*F)|GetThis Not_A(*SKIP)(?!)
|GetThis
Note that the parentheses around GetThis have disappeared. Whenever
the engine is able to match Not_A, the (*SKIP)(*FAIL) construct
causes it to reject that entire chunk of text and start the next
match attempt immediately afterwards. Whenever the engine is not able
to match Not_A, it jumps to the right branch of the alternation | and
tries to match GetThis. If this fails, the engine starts the next
match attempt at the next starting position in the subject text, as
always.
If we want to avoid three contexts A, B and C, our technique used to
do this: Not_A|Not_B|Not_C|(GetThis)
In Perl and PHP, we can instead say something like one of these:
Not_A(*SKIP)(*FAIL)|Not_B(*SKIP)(*F)|Not_C(*SKIP)(?!)|GetThis
(?:Not_A|Not_B|Not_C)(*SKIP)(*FAIL)|(GetThis)
Back the the article's Table of Contents
Code Samples
To complete this article, I'd like to provide a full implementation
in several common languages.
A Call to Help
May 2014. I'm calling for your help to translate the examples
provided to languages in which you are fluent (see code translators
needed). In advance, thank you.
The six tasks performed by the code samples
The code performs the six most common regex tasks. The first four
tasks answer the most common questions we use regex for:
Does the string match?
How many matches are there?
What is the first match?
What are all the matches?
The last two tasks perform two other common regex tasks:
Replace all matches
Split the string
Learn a new engine!
The code samples should allow even complete beginners to pick code
fragments that suit their needs and tweak them to their liking.
Please rest assured that beginner is not a condescending term here,
and I am expecting "advanced beginners" to take advantage of the
code. If you are proficient in regex in the context of one
programming language, you may be curious to test out other engines,
but also worried about the learning curve. Apart from illustrating
various uses of the technique, the code samples allow you to start
experimenting in a variety of regex flavors.
The assignment for the code samples
All the code samples tackle the same assignment. Our assignment is to
match Tarzan followed by any number of digits, for instance Tarzan111
, except:
1. between quotes, as in "Tarzan123",
2. somewhere inside curly braces, as in { Jane Tarzan123 }
For this assignment, I will use \d without attempting to distinguish
between ASCII digits and Unicode digits, as that is not the point of
the exercise. Just be aware that in some engines \d only matches the
ASCII digits 0 to 9, while in others it also matches digits in other
alphabets. If you want to be consistent, use [0-9]
The Test Strings
To test the code, we'll use one string that produces two matches and
a small variation that should produce none.
1. The string below should produce two matches: Tarzan11 and Tarzan22
Jane" "Tarzan12" Tarzan11@Tarzan22 {4 Tarzan34}
2. To test failure cases, I suggest you capitalize two z characters
as in the string below, which should produce no matches:
Jane" "Tarzan12" TarZan11@TarZan22 {4 Tarzan34}
The Regex
Here is the regex we'll use:
{[^}]+}|"Tarzan\d+"|(Tarzan\d+)
1. The first part of the alternation {[^}]+} matches and neutralizes
any content between curly quotes.
2. The second part of the alternation "Tarzan\d+" matches and
neutralizes instances where the sought string is embedded within
double quotes. You may ask why I didn't simply neutralize any content
between double quotes in similar fashion to the first part of the
alternation, using "[^"]+". For most strings, that would have worked,
but if you carefully inspect the test string, you'll see that I
sneaked in an extra double quote after Jane. I did so to illustrate a
safe regex work practice. See, if for any reason the subject string
has an odd number of double quotes as is the case here, you cannot be
sure that two quotes matched by "[^"]+" belong together. Indeed, for
our test string, that code would match a single space within double
quotes, and the regex would (wrongly) capture Tarzan12 into Group 1.
Therefore, when working with quotes, being specific as in "Tarzan\d+"
is safer. In the case of braces (where there are distinct characters
for the left and right sides), the risk of mismatches is far lower.
3. The third part of the alternation (Tarzan\d+) matches Tarzan and
the following digits and captures the match into Group 1.
Here are jump points to code samples in various languages.
Implemented
PHP
C#
Python
Java
JavaScript
Ruby
Perl
VB.NET
Not Yet Implemented
Visual C++
Scala
Other language of your choice
PHP Code Sample
For PHP, I'll provide two samples. The first illustrates the main
technique on this page. The second illustrates the (*SKIP)(*F)
variation specific to Perl and PHP, which is a little lighter.
Sample #1: The Core Technique
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
\n";
if(empty($matches)) echo "No
\n";
else echo "Yes
\n";
// Task 2: How many matches are there?
echo "\n
*** Number of Matches ***
\n";
echo count($matches)."
\n";
// Task 3: What is the first match?
echo "\n
*** First Match ***
\n";
if(!empty($matches)) echo array_values($matches)[0]."
\n";
// Task 4: What are all the matches?
echo "\n
*** Matches ***
\n";
if(!empty($matches)) {
foreach ($matches as $match) echo $match."
\n";
}
// Task 5: Replace the matches
$replaced = preg_replace_callback(
$regex,
// in the callback function, if Group 1 is empty,
// set the replacement to the whole match,
// i.e. don't replace
function($m) { if(empty($m[1])) return $m[0];
else return "Superman";},
$subject);
echo "\n
*** Replacements ***
\n";
echo $replaced."
\n";
// Task 6: Split
// Start by replacing by something distinctive,
// as in Step 5. Then split.
$splits = explode("Superman",$replaced);
echo "\n
*** Splits ***
\n";
echo ""; print_r($splits); echo "
";
?>
Sample #2: The (*SKIP)(*F) Variation
This sample implements the technique explained in the Variation for
Perl and PCRE section.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
\n";
if($count) echo "Yes
\n";
else echo "No
\n";
// Task 2: How many matches are there?
echo "\n
*** Number of Matches ***
\n";
if($count) echo count($matches[0])."
\n";
else echo "0
\n";
// Task 3: What is the first match?
echo "\n
*** First Match ***
\n";
if($count) echo $matches[0][0]."
\n";
// Task 4: What are all the matches?
echo "\n
*** Matches ***
\n";
if($count) {
foreach ($matches[0] as $match) echo $match."
\n";
}
// Task 5: Replace the matches
$replaced = preg_replace($regex,"Superman",$subject);
echo "\n
*** Replacements ***
\n";
echo $replaced."
\n";
// Task 6: Split
$splits = preg_split($regex,$subject);
echo "\n
*** Splits ***
\n";
echo ""; print_r($splits); echo "
";
?>
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
C# Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
using System;
using System.Text.RegularExpressions;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main() {
string s1 = @"Jane"" ""Tarzan12"" Tarzan11@Tarzan22 {4 Tarzan34}";
var myRegex = new Regex(@"{[^}]+}|""Tarzan\d+""|(Tarzan\d+)");
var group1Caps = new List();
Match matchResult = myRegex.Match(s1);
// put Group 1 captures in a list
while (matchResult.Success) {
if (matchResult.Groups[1].Value != "") {
group1Caps.Add(matchResult.Groups[1].Value);
}
matchResult = matchResult.NextMatch();
}
///////// The six main tasks we're likely to have ////////
// Task 1: Is there a match?
Console.WriteLine("*** Is there a Match? ***");
if(group1Caps.Any()) Console.WriteLine("Yes");
else Console.WriteLine("No");
// Task 2: How many matches are there?
Console.WriteLine("\n" + "*** Number of Matches ***");
Console.WriteLine(group1Caps.Count);
// Task 3: What is the first match?
Console.WriteLine("\n" + "*** First Match ***");
if(group1Caps.Any()) Console.WriteLine(group1Caps[0]);
// Task 4: What are all the matches?
Console.WriteLine("\n" + "*** Matches ***");
if (group1Caps.Any()) {
foreach (string match in group1Caps) Console.WriteLine(match);
}
// Task 5: Replace the matches
string replaced = myRegex.Replace(s1, delegate(Match m) {
// m.Value is the same as m.Groups[0].Value
if (m.Groups[1].Value == "") return m.Value;
else return "Superman";
});
Console.WriteLine("\n" + "*** Replacements ***");
Console.WriteLine(replaced);
// Task 6: Split
// Start by replacing by something distinctive,
// as in Step 5. Then split.
string[] splits = Regex.Split(replaced,"Superman");
Console.WriteLine("\n" + "*** Splits ***");
foreach (string split in splits) Console.WriteLine(split);
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
Python Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
import re
# import regex # if you like good times
# intended to replace `re`, the regex module has many advanced
# features for regex lovers. http://pypi.python.org/pypi/regex
subject = 'Jane"" ""Tarzan12"" Tarzan11@Tarzan22 {4 Tarzan34}'
regex = re.compile(r'{[^}]+}|"Tarzan\d+"|(Tarzan\d+)')
# put Group 1 captures in a list
matches = [group for group in re.findall(regex, subject) if group]
######## The six main tasks we're likely to have ########
# Task 1: Is there a match?
print("*** Is there a Match? ***")
if len(matches)>0:
print ("Yes")
else:
print ("No")
# Task 2: How many matches are there?
print("\n" + "*** Number of Matches ***")
print(len(matches))
# Task 3: What is the first match?
print("\n" + "*** First Match ***")
if len(matches)>0:
print (matches[0])
# Task 4: What are all the matches?
print("\n" + "*** Matches ***")
if len(matches)>0:
for match in matches:
print (match)
# Task 5: Replace the matches
def myreplacement(m):
if m.group(1):
return "Superman"
else:
return m.group(0)
replaced = regex.sub(myreplacement, subject)
print("\n" + "*** Replacements ***")
print(replaced)
# Task 6: Split
# Start by replacing by something distinctive,
# as in Step 5. Then split.
splits = replaced.split('Superman')
print("\n" + "*** Splits ***")
for split in splits:
print (split)
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
Java Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;
class Program {
public static void main (String[] args) throws java.lang.Exception {
String subject = "Jane\" \"Tarzan12\" Tarzan11@Tarzan22 {4 Tarzan34}";
Pattern regex = Pattern.compile("\\{[^}]+\\}|\"Tarzan\\d+\"|(Tarzan\\d+)");
Matcher regexMatcher = regex.matcher(subject);
List group1Caps = new ArrayList();
// put Group 1 captures in a list
while (regexMatcher.find()) {
if(regexMatcher.group(1) != null) {
group1Caps.add(regexMatcher.group(1));
}
} // end of building the list
///////// The six main tasks we're likely to have ////////
// Task 1: Is there a match?
System.out.println("*** Is there a Match? ***");
if(group1Caps.size()>0) System.out.println("Yes");
else System.out.println("No");
// Task 2: How many matches are there?
System.out.println("\n" + "*** Number of Matches ***");
System.out.println(group1Caps.size());
// Task 3: What is the first match?
System.out.println("\n" + "*** First Match ***");
if(group1Caps.size()>0) System.out.println(group1Caps.get(0));
// Task 4: What are all the matches?
System.out.println("\n" + "*** Matches ***");
if(group1Caps.size()>0) {
for (String match : group1Caps) System.out.println(match);
}
// Task 5: Replace the matches
// if only replacing, delete the line with the first matcher
// also delete the section that creates the list of captures
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
if(m.group(1) != null) m.appendReplacement(b, "Superman");
else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
System.out.println("\n" + "*** Replacements ***");
System.out.println(replaced);
// Task 6: Split
// Start by replacing by something distinctive,
// as in Step 5. Then split.
String[] splits = replaced.split("Superman");
System.out.println("\n" + "*** Splits ***");
for (String split : splits) System.out.println(split);
} // end main
} // end Program
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
JavaScript Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
Ruby Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
subject = 'Jane"" ""Tarzan12"" Tarzan11@Tarzan22 {4 Tarzan34}'
regex = /{[^}]+}|"Tarzan\d+"|(Tarzan\d+)/
# put Group 1 captures in an array
group1Caps = []
subject.scan(regex) {|m|
group1Caps << $1 if !$1.nil?
}
######## The six main tasks we're likely to have ########
# Task 1: Is there a match?
puts("*** Is there a Match? ***")
if group1Caps.length > 0
puts "Yes"
else
puts "No"
end
# Task 2: How many matches are there?
puts "\n*** Number of Matches ***"
puts group1Caps.length
# Task 3: What is the first match?
puts "\n*** First Match ***"
if group1Caps.length > 0
puts group1Caps[0]
end
# Task 4: What are all the matches?
puts "\n*** Matches ***"
if group1Caps.length > 0
group1Caps.each { |x| puts x }
end
# Task 5: Replace the matches
replaced = subject.gsub(regex) {|m|
if $1.nil?
m
else
"Superman"
end
}
puts "\n*** Replacements ***"
puts replaced
# Task 6: Split
# Start by replacing by something distinctive,
# as in Step 5. Then split.
splits = replaced.split(/Superman/)
puts "\n*** Splits ***"
splits.each { |x| puts x }
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
Perl Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
or leave the site to view an online demo
#!/usr/bin/perl
$regex = '{[^}]+}|"Tarzan\d+"|(Tarzan\d+)';
$subject = 'Jane" "Tarzan12" Tarzan11@Tarzan22 {4 Tarzan34}';
# put Group 1 captures in an array
my @group1Caps = ();
while ($subject =~ m/$regex/g) {
print $1 . "\n";
if (defined $1) {push(@group1Caps,$1); }
}
######## The six main tasks we're likely to have ########
# Task 1: Is there a match?
print "*** Is there a Match? ***\n";
if ( @group1Caps > 0) { print "Yes\n"; }
else { print ("No\n"); }
# Task 2: How many matches are there?
print "\n*** Number of Matches ***\n";
print scalar(@group1Caps);
# Task 3: What is the first match?
print "\n\n*** First Match ***\n";
if ( @group1Caps > 0) { print $group1Caps[0]; }
# Task 4: What are all the matches?
print "\n\n*** Matches ***\n";
if ( @group1Caps > 0) {
foreach(@group1Caps) { print "$_\n"; }
}
# Task 5: Replace the matches
# or: s/$regex/$1? "Superman":$&/eg
($replaced = $subject) =~ s/$regex/
if (defined $1) { "Superman"; } else {$&;} /eg;
print "\n*** Replacements ***\n";
print $replaced . "\n";
# Task 6: Split
# Start by replacing by something distinctive,
# as in Step 5. Then split.
@splits = split(/Superman/, $replaced);
print "\n*** Splits ***\n";
foreach(@splits) { print "$_\n"; }
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
VB.NET Code Sample
If you see ways to improve the code, please leave a comment.
Please note that usually you will choose to perform only one of the
six tasks in the code, so your own code will be much shorter.
Click to Show / Hide code
(The code compiles perfectly in VS2015, but no online demo supplied
because the VB.NET in ideone chokes on anonymous functions.)
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim MyRegex As New Regex("{[^}]+}|""Tarzan\d+""|(Tarzan\d+)")
Dim Subject As String = "Jane"" ""Tarzan12"" Tarzan11@Tarzan22 {4 Tarzan34} "
Dim Group1Caps As New List(Of String)()
Dim MatchResult As Match = MyRegex.Match(Subject)
' put Group 1 captures in a list
While MatchResult.Success
If MatchResult.Groups(1).Value <> "" Then
Group1Caps.Add(MatchResult.Groups(1).Value)
End If
MatchResult = MatchResult.NextMatch()
End While
'///////// The six main tasks we're likely to have ////////
'// Task 1: Is there a match?
Console.WriteLine("*** Is there a Match? ***")
If(Group1Caps.Any()) Then
Console.WriteLine("Yes")
Else
Console.WriteLine("No")
End If
'// Task 2: How many matches are there?
Console.WriteLine(vbCrLf & "*** Number of Matches ***")
Console.WriteLine(Group1Caps.Count)
'// Task 3: What is the first match?
Console.WriteLine(vbCrLf & "*** First Match ***")
If(Group1Caps.Any()) Then Console.WriteLine(Group1Caps(0))
'// Task 4: What are all the matches?
Console.WriteLine(vbCrLf & "*** Matches ***")
If (Group1Caps.Any()) Then
For Each match as String in Group1Caps
Console.WriteLine(match)
Next
End If
'// Task 5: Replace the matches
Dim Replaced As String = myRegex.Replace(Subject,
Function(m As Match)
If (m.Groups(1).Value = "") Then
Return m.Groups(0).Value
Else
Return "Superman"
End If
End Function)
Console.WriteLine(vbCrLf & "*** Replacements ***")
Console.WriteLine(Replaced)
' Task 6: Split
' Start by replacing by something distinctive,
' as in Step 5. Then split.
Dim Splits As Array = Regex.Split(replaced,"Superman")
Console.WriteLine(vbCrLf & "*** Splits ***")
For Each Split as String in Splits
Console.WriteLine(Split)
Next
Console.WriteLine(vbCrLf & "Press Any Key to Exit.")
Console.ReadKey()
End Sub
End Module
Back to the Code Samples explanation and languages
Back the the article's Table of Contents
Code Translators Needed
I would love to enlist your help so the page can provide working code
in more languages. Please see the list of languages for languages
currently implemented and missing.
If you wish, you will be duly acknowledged with your name or an alias
of your choice.
Are you willing to help? Fantastic. To make things easy for me, your
code needs to mirror the specs of the other samples. Here are the
requirements that come to mind:
Completeness. The idea is to provide code that someone who has
never used your language is able to plug in to an IDE, compile (if
needed) and run. So please include any opening braces and the few
needed lines to import any relevant libraries.
Conciseness. By the same token, please ommit any unneeded fluff,
such as unneeded libraries and classes.
Same example. To keep things consistent, please use the regex and
subject string provided.
Six tasks. The code must include separate sections that could be
run separately if needed, addressing the four common tasks
illustrated by the code already on the page: (i) checking whether
there is a match, (ii) counting the matches, (iii) returning the
first match, (iv) returning all matches, (v) replacing all matches,
(vi) splitting the string.
Formatted output. If you run the existing demos, you'll see that
they output certain strings at each step to inform us of where we are
in the code. Your code should output those same strings.
Link to a working demo. For consistency, if ideone.com supports
your language, please use it.
If you paste your code in the comment form it may not make it to me
intact, but you can paste an ideone.com link or a brief message. I'll
reply. Html won't work in the comment form.
A million thanks in advance!
Well, I think that's about all I have to say about this technique at
the moment. Writing it was a big journey. I hope you had a blast
reading it.
Wishing you loads of fun on your travels in regexland,
Rex
At this stage you might like to treat yourself to some
Regex Humor
...or just visit the next page.
next
Regex Cookbook
Regex Rex
Ask Rex
Leave a Comment
1-7 of 7 Threads
Ivan
July 05, 2020 - 15:16
Subject: An error in the JavaScript Code Sample
Hi,
Line 37 of the JS code,
"if (group1 == "" ) return m;"
should be
"if (group1 == undefined ) return m;"
for the code to work correctly.
Reply to Ivan
Rex
July 05, 2020 - 21:11
Subject: RE: An error in the JavaScript Code Sample
Thank you Ivan. The code worked when I wrote it, but JS specs change
over time and vary from platform to platform, so I'm glad you let me
know about the latest. Warm regards, Rex
Rex
September 29, 2015 - 10:42
Subject: RE: nitpick
Hi Toomas, Thank you so much for your nitpicks, man! I really
appreciate them. Perl is not my idiom so I'm sure what I have is
quite heavy. Added your Perl code as a comment line above what was
there. Fixed the others. Wishing you a fun week, Rex
Rex
September 27, 2015 - 12:30
Subject: RE: Typo
Hi Omer, Thank you very much for reporting typos. I really appreciate
it. Fixed. Wishing you a fun weekend, Rex
Omer - Earth
September 27, 2015 - 11:54
Subject: Typo
First sentence after option 3 heading: s/that/than/
Joel
September 27, 2015 - 04:20
Subject: Excellent article - thanks for the regex help!
Very well done. All your step-by-step examples make this article
superb.
Lane
July 07, 2014 - 09:15
Subject: When the simple answer is the most profound
That is so simple that it's genius! I just started to learn regex and
am glad I found this site so I don't waste time struggling with it
when you cut right to the chase. Thanks!
Joe - Texas
June 03, 2014 - 13:14
Subject: Thank you!
You are awesome. Thanks for the trick and the page.
Leave a Comment
[ ] * Your name
[ ] * Email (it will not be shown)
[ ] Your location
Subject: [ ]
All comments are moderated.
Link spammers, this won't work for you.
[ ]
To prevent automatic spam, may I gently ask that you go through these
crazy hoops...
[Submit]
x Fundamentals
* Regex Tutorial
* Regex vs. Regex
* Quick Reference
* 100 Uses for Regex
* Regex Style Guide
Black Belt Program
* All (? ... ) Syntax
* Boundaries++
* Anchors
* Capture & Back
* Flags & Modifiers
* Lookarounds
* Quantifiers
* Explosive Quantifiers
* Conditionals
* Recursion
* Class Operations
* Backtracking Control
* Regex Gotchas
* Syntax Tricks
* PCRE Callouts
* Quantifier capture
Regex in Action
For awesome tricks:
scroll down!
* Cookbook
* Cool Regex Classes
* Regex Optimizations
* PCRE: Grep and Test
* Perl One-Liners
* Amazing Shortcuts
Tools & More
* Regex Tools
* RegexBuddy
* Regex Humor
* Regex Books & Links
Tricks
* The Best Regex Trick
* Conditional Sub
* Line Numbers
* Numbers in English
Languages
* PCRE Doc & Log
* Regex with Perl
* Regex with C#
* Regex with PHP
* Regex with Python
* Regex with Java
* Regex with JavaScript
* Regex with Ruby
* Regex with VB.NET
Matering Regular Expressions
A must-read
RegexBuddy 4 is
the best regex tool!
Get the Free Trial
Huge RB Tutorial
Regex Rex
Ask Rex
[ ] Search
(c) Copyright RexEgg.com