Keywords: Regular Expressions | Horizontal Whitespace | Perl | Unicode | Character Classes
Abstract: This article provides an in-depth exploration of various methods to match horizontal whitespace characters (such as spaces and tabs) while excluding newlines in regular expressions. It focuses on the \h character class introduced in Perl v5.10+, which specifically matches horizontal whitespace characters including relevant characters from both ASCII and Unicode. The article also compares alternative approaches like the double-negative method [^\S\r\n], Unicode properties \p{Blank}, and direct enumeration, analyzing their respective use cases and trade-offs. Through detailed code examples and performance comparisons, it helps developers choose the most appropriate matching strategy based on specific requirements.
Core Concepts of Horizontal Whitespace Matching
In text processing, it is often necessary to distinguish between horizontal whitespace characters (like spaces and tabs) and vertical whitespace characters (like newlines). The traditional [ \t] approach, while simple, has limited functionality and cannot cover various horizontal whitespace characters in Unicode. Perl v5.10 and later versions introduced the specialized \h character class to match all horizontal whitespace characters, including those from both ASCII and Unicode character sets.
Using the \h Character Class
\h is the most concise method for matching horizontal whitespace characters. It encompasses the following characters:
U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE
The following Perl code demonstrates the use of \h:
#!/usr/bin/env perl
use strict;
use warnings;
my $text = "Hello\tWorld \u00A0Next";
if ($text =~ /\h+/) {
print "Found horizontal whitespace\n";
}
Double-Negative Character Class Method
For regex engines that do not support \h, the double-negative character class [^\S\r\n] can be used. This method is based on De Morgan's laws, excluding carriage return (\r) and newline (\n) from \s (which matches all whitespace characters).
#!/usr/bin/env perl
use strict;
use warnings;
my $ws_not_crlf = qr/[^\S\r\n]/;
for (' ', '\f', '\t', '\r', '\n') {
my $qq = qq["$_"];
printf "%-4s => %s\n", $qq,
(eval $qq) =~ $ws_not_crlf ? "match" : "no match";
}
Output:
" " => match
"\f" => match
"\t" => match
"\r" => no match
"\n" => no match
Unicode Property Matching
Unicode provides the \p{Blank} and \p{HorizSpace} properties, which are equivalent to \h. These properties are particularly useful when precise control over character matching is required.
#!/usr/bin/env perl
use strict;
use warnings;
my $text = "Hello\u2003World"; # Using EM SPACE
if ($text =~ /\p{Blank}+/) {
print "Found blank characters\n";
}
Direct Enumeration Method
In ASCII environments, horizontal whitespace characters can be directly enumerated: [\t\f\cK ]. This method is straightforward but does not support Unicode characters.
#!/usr/bin/env perl
use strict;
use warnings;
my $text = "Hello\tWorld";
if ($text =~ /[\t ]+/) {
print "Found ASCII horizontal whitespace\n";
}
Method Comparison and Selection Guidelines
When choosing a matching method, consider the following factors:
- Perl v5.10+ Environment: Prefer
\hfor concise and fully functional code - Cross-Platform Compatibility: Use
[^\S\r\n], supported by most regex engines - Unicode Handling: Use
\p{Blank}or\p{HorizSpace} - Simple ASCII Scenarios: Use
[\t ]or[\t\f\cK ]
Practical Application Example
The following example demonstrates the use of horizontal whitespace in phone number matching:
#!/usr/bin/env perl
use strict;
use warnings;
my $phone_pattern = qr/(\+|0|\()(?:[\d()-]|[^\S\r\n]){6,20}\d/;
my $phone = "+1 (555) 123-4567";
if ($phone =~ $phone_pattern) {
print "Valid phone number: $&\n";
}
Performance Considerations
In performance-sensitive scenarios, \h is generally the optimal choice as it is a specially optimized character class. The double-negative method [^\S\r\n] might be slightly slower in some engines due to the need to compute character class complements.
Conclusion
Matching horizontal whitespace characters while excluding newlines is a common requirement in text processing. The \h character class offers the most elegant solution, especially in Perl environments. For cases requiring cross-platform compatibility or specific Unicode support, the double-negative method and Unicode properties are reliable alternatives. Developers should choose the most appropriate method based on specific needs and runtime environments.