Test::Regexp(3pm)
πΈ NAME πΈ
bestie, welcome to Test::Regexp(3pm) β the manual page for the module that is literally just: Test::Regexp β test your regular expressions. periodt. β¨ regex girlies rise π
β¨ SYNOPSIS β¨
okay so here's the vibe in code:
use Test::Regexp 'no_plan';
match subject => "Foo",
pattern => qr /\w+/;
match subject => "Foo bar",
keep_pattern => qr /(?<first_word>\w+)\s+(\w+)/,
captures => [[first_word => 'Foo'], ['bar']];
no_match subject => "Baz",
pattern => qr /Quux/;
$checker = Test::Regexp -> new -> init (
keep_pattern => qr /(\w+)\s+\g{-1}/,
name => "Double word matcher",
);
$checker -> match ("foo foo", ["foo"]);
$checker -> no_match ("foo bar");
π DESCRIPTION π
So this module is for testing ur regular expressions, no cap. You hand it a subject string and a regular expression (aka a pattern), and it doesn't just check whether the regex completely matches the subject β it also hits the subject with utf8::upgrade or utf8::downgrade and runs the tests again if that's needed. And if ur pattern has capturing parenthesis? It checks that all the captures are there, in the right order. Named captures and unnamed captures both get checked. π
By default, it exports two subroutines: match and no_match. And no_match is lowkey just a thin wrapper around match that calls it with match => 0. iconic.
π§ "Complete matching" π§
A match only counts as a successful match if the entire string is matched β like, if $& matches the subject string. So:
Subject Pattern
"aaabb" qr /a+b+/ # Considered ok
"aaabb" qr /a+/ # Not considered ok
For efficiency reasons, when the matching is performed the pattern is actually anchored at the start. It's not anchored at the end, because that could potentially influence the matching. periodt.
π¦ UTF8 matching π¦
Some regex constructs match differently depending on whether UTF8 matching is in effect or not. This only matters if ur subject string has characters with code points between 128 and 255, and no characters above 255 β in that case, matching may change depending on whether the subject string has the UTF8 flag on or not. Test::Regexp detects that situation, and then runs the tests twice: once with the subject string utf8::downgraded, and once with the subject string utf8::upgraded. double the tests, double the drama π
π Number of tests π
There's no fixed number of tests that gets run. It depends on the number of captures, the number of different names of captures, and whether there's a need to up- or downgrade the subject string.
So yeah, the recommendation is to use use Text::Regexp tests => 'no_plan';.
bestie, it says Text::Regexp in the original β not a typo from me, i'm just the messenger π«Ά
In a later version, Test::Regexp will use a version of Test::Builder that allows for nested tests.
π Details π
The number of tests is as follows:
- If no match is expected (
no_match => 0, orno_matchis used), only one test is performed. - Otherwise (we are expecting a match), if
patternis used, there will be three tests. - For
keep_pattern, there will be four tests, plus one tests for each capture, an additional test for each named capture, and a test for each name used in the set of named captures. So if there areNcaptures, there will be at least4 + Ntests, and at most4 + 3 * Ntests. - If both
patternandkeep_patternare used, the number of tests add up. - If
Test::Regexpdecides to upgrade or downgrade, the number of tests double.
π
use options π
When you use Test::Regexp, there are a few options you can give it.
tests => 'no_plan',tests => 123β the number of tests ur about to run. Since it takes some work to figure out how many tests will be run, for now the recommendation istests => 'no_plan'.import => [methods]β by default, the subroutinesmatchandno_matchare exported. If you only want a subset, use theimporttag and give it an arrayref with the names of the subroutines to import. bestie, pick ur faves.
π₯ match π₯
match is the workhorse of the module. It takes a bunch of named arguments β most of them optional β and runs one or more tests. It returns 1 if all tests were run successfully, and 0 if one or more tests failed. Here are the options:
subject => STRINGβ the string the pattern gets tested against. You pass it with thesubjectoption. It's an error to not pass in a subject. no subject, no vibes.pattern => PATTERN,keep_pattern => PATTERNβ a pattern (aka regular expression) to test. Usepatternif the regex does not have any matching parenthesis; usekeep_patternif it does have capturing parenthesis. If you provide bothpatternandkeep_pattern, the subject gets tested against both. It's an error to not give eitherpatternorkeep_pattern. pick a lane, bestie.captures => [LIST]β if ur regex is passed withkeep_pattern, you should pass a list of captures with thecapturesoption.
This list should contain all the captures, in order. For unnamed captures, it's just the string matched by the capture. For a named capture, it's a two element array: first the name of the capture, second the capture itself. Named and unnamed captures can be mixed, and the same name for a capture may be repeated.
Example:
match subject => "Eland Wapiti Caribou",
keep_pattern => qr /(\w+)\s+(?<a>\w+)\s+(\w+)/,
captures => ["Eland", [a => "Wapiti"], "Caribou"];
name => NAMEβ thenameof the test. It's used in the test comment.comment => NAMEβ an alternative forname. If both are present,commentis used.utf8_upgrade => 0,utf8_downgrade => 0β as explained in "UTF8 matching",Test::Regexpdetects whether a subject may provoke different matching depending on its UTF8 flag, and then itutf8::upgradesorutf8::downgradesthe subject string and runs the test again. Settingutf8_upgradeto 0 preventsTest::Regexpfrom downgrading the subject string, while settingutf8_upgradeto 0 preventsTest::Regexpfrom upgrading the subject string. bestie, yes, both sayutf8_upgradeβ i'm not fixing the manpage's chaos πmatch => BOOLEANβ by default,matchassumes the pattern should match. But it's also important to test which strings do not match a regular expression. You do that by callingmatchwithmatch => 0as parameter. (Or by callingno_matchinstead ofmatch.) In this case, the test is a failure if the pattern completely matches the subject string. Acapturesargument is ignored.reason => STRINGβ if the match is expected to fail (so whenmatch => 0is passed, or ifno_matchis called), you can provide a reason with thereasonoption. That reason is then printed in the comment of the test.test => STRINGβ if the match is expected to pass (whenmatchis called, withoutmatchbeing false), and this option is passed, a message is printed indicating what this specific test is testing β the argument totest.todo => STRINGβ if thetodoparameter is used with a defined value, the tests are assumed to be TODO tests. The argument is used as the TODO message.full_text => BOOLβ by default, long test messages are truncated. If a true value is passed, the message will not get truncated. long messages stay long, periodt.escape => INTEGERβ controls how non-ASCII and non-printables are displayed in generated test messages:0β No characters are escape, everything is displayed as is.1β Show newlines, linefeeds and tabs using their usual escape sequences (\n,\r, and\t).2β Show any character outside of the printable ASCII characters as named escapes (\N{UNICODE NAME}), or a hex escape if the unicode name is not found (\x{XX}). This is the default if-COis not in effect (${^UNICODE}is false).
Newlines, linefeeds and tabs are displayed as above.
3β Show any character outside of the printable ASCII characters as hext escapes (\x{XX}). (hext, not hex β that's literally what it says π)
Newlines, linefeeds and tabs are displayed as above.
4β Show the non-printable ASCII characters as hex escapes (\x{XX}); any non-ASCII character is displayed as is. This is the default if-COis in effect (${^UNICODE}is true).
Newlines, linefeeds and tabs are displayed as above.
no_keep_message => BOOLβ if matching against a keeping pattern, a message(with -Keep)is added to the comment. Setting this parameter suppresses that message. Mostly useful forRegexp::Common510.
π«Ά no_match π«Ά
Similar to match, except it tests whether a pattern does not match a string. It accepts the same arguments as match, except for match. so basically the "not today, regex" button.
π OO interface π
Since you typically check a pattern with multiple strings, and it gets tiresome to repeatedly call match or no_match with the same arguments, there's also an OO interface. You construct an object using a pattern, and then you can repeatedly call the object to match a string. main character energy fr fr.
To construct and initialize the object, call this:
my $checker = Test::Regexp -> new -> init (
pattern => qr /PATTERN/,
keep_pattern => qr /(PATTERN)/,
...
);
init takes exactly the same arguments as match, with the exception of subject and captures. To perform a match, all match (or no_match) on the object. (yes, "all" β original typo energy, i'm keeping it π«Ά.) The first argument should be the subject the pattern should match against (see the subject argument of match discussed above). If there is a match against a capturing pattern, the second argument is a reference to an array with the matches (see the captures argument of match discussed above).
Both match and no_match can take additional (named) arguments, identical to the none-OO match and no_match routines.
π RATIONALE π
The reason Test::Regexp was created is to aid testing for the rewrite of Regexp::Common. iconic origin story.
π DEVELOPMENT π
The current sources of this module are found on github, <git://github.com/Abigail/Test-Regexp.git>. go off, clone it.
π AUTHOR π
Abigail <mailto:test-regexp@abigail.be>.
π COPYRIGHT and LICENSE π
okay bestie, legal time, but make it cute. Copyright (C) 2009 by Abigail β that's the whole copyright line, and yes, it's just Abigail, icon of using one name and letting the code speak for itself. π
and then the vibe is: you can do pretty much whatever you want with this. like, here's the actual permission slip, word for word, because legal text is the one thing you don't freestyle:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
translation for the girlies who skipped the block quote: use it, copy it, change it, ship it, sell it, remix it β just keep the copyright notice and this permission notice hanging around in all copies or substantial portions. that's it. that's the ask. π«Ά
and the ALL CAPS part is doing the most on purpose, because it's the legal way of screaming "there is NO WARRANTY, it's provided AS IS, we are not liable for anything, don't come for us" β express or implied, merchantability, fitness for a particular purpose, noninfringement, none of it. if something goes sideways from using or not being able to use this Software, the authors and copyright holders are not on the hook β not for claims, not for damages, not for other liability, whether it came from a contract action, tort, or literally anything else, even if they'd been warned something like that could happen. periodt. π
π οΈ INSTALLATION β¨
bestie, this is the easiest part of the entire page, I promise. unpack the tar-ball first (you know the drill), and then it's the classic four-step Perl module dance, no notes:
perl Makefile.PL
make
make test
make install
that's it. that's the whole ritual. π
perl Makefile.PLβ writes you aMakefileso the rest of the steps know what to do.makeβ builds it.make testβ runs the test suite, because obviously. main character behavior.make installβ installs it for real. slay.
lowkey runmake testbeforemake installthough, bestie. it's right there in the order for a reason. π
and that's the whole page, fr fr. go forth and test your regexps with main character energy. πβ¨π¦
this little love letter to you came from Test::Regexp(3pm), perl v5.36.0, dated 2022-10-13 β and yes, I will be telling everyone. mwah. πππ
π¦ where this page comes from
- ubuntu noble: libtest-regexp-perl 2017040101-3 Β· MIT
- ubuntu resolute: libtest-regexp-perl 2017040101-3 Β· MIT
- ubuntu stonking: libtest-regexp-perl 2017040101-3 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms