使用反向引用的字母顺序正则表达式
Alphabetic order regex using backreferences
我最近遇到了一个难题,要找到匹配的正则表达式:
5-character-long strings comprised of lowercase English letters in ascending ASCII order
有效示例包括:
aaaaa
abcde
xxyyz
ghost
chips
demos
无效示例包括:
abCde
xxyyzz
hgost
chps
我目前的解决方案很笨拙。我使用正则表达式:
(?=^[a-z]{5}$)^(a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*)$
它使用非消耗捕获组断言字符串长度为5,然后验证该字符串是否按顺序由小写英文字母组成(see Rubular)。
相反,我想在字符 classes 中使用反向引用。类似于:
^([a-z])([-z])([-z])([-z])([-z])$
我脑海中的解决方案(see Rubular)的逻辑是捕获第一个字符[a-z],将其用作第二个字符class中的反向引用,依此类推。但是,</code>、<code>
...字符 classes 似乎指的是 ASCII 值 1、2...有效匹配任何四或五个字符的字符串。
我有两个问题:
- 我可以在角色 classes 中使用反向引用来检查升序字符串吗?
- 这个难题有没有更简单的解决方案?
我将此答案作为评论而不是答案发布,因为它的格式比评论更好。
与您的问题相关:
- Can I use back references in my character classes to check for ascending order strings?
不,你不能。如果您查看 backref regular-expressions 部分,您将找到以下文档:
Parentheses and Backreferences Cannot Be Used Inside Character Classes
Parentheses cannot be used inside character classes, at least not as metacharacters. When you put a parenthesis in a character class, it is treated as a literal character. So the regex [(a)b] matches a, b, (, and ).
Backreferences, too, cannot be used inside a character class. The in a regex like (a)[b] is either an error or a needlessly escaped literal 1. In JavaScript it's an octal escape.
关于你的第二个问题:
- Is there any less-hacky solution to this puzzle?
恕我直言,你的正则表达式非常好,你可以像这样在开始时将它缩短一点:
(?=^.{5}$)^a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*$
^--- Here
如果您愿意使用 Perl (!),这将有效:
/^([a-z])((??{"[-z]"}))((??{"[-z]"}))((??{"[-z]"}))(??{"[-z]"})$/
由于有人使用 Perl 打破僵局,所以这是一个
我猜 Perl 解决方案 ..
请注意,这是一个基本的非正则表达式解决方案,恰好是
塞入 Perl 正则表达式中的代码结构。
有趣的是,如果有一天你需要协同
regex/code 这是一个不错的选择。
那么有可能不是简单的 [a-z]
字符,而是
在它的位置使用非常复杂的模式并使用检查与最后。
那就是力量!!
正则表达式 ^(?:([a-z])(?(?{ $last gt })(?!)|(?{ $last = }))){5}$
Perl 代码
use strict;
use warnings;
$/ = "";
my @DAry = split /\s+/, <DATA>;
my $last;
for (@DAry)
{
$last = '';
if (
/
^ # BOS
(?: # Cluster begin
( [a-z] ) # (1), Single a-z letter
# Code conditional
(?(?{
$last gt # last > current ?
})
(?!) # Fail
| # else,
(?{ $last = }) # Assign last = current
)
){5} # Cluster end, do 5 times
$ # EOS
/x )
{
print "good $_\n";
}
else {
print "bad $_\n";
}
}
__DATA__
aaaaa
abcde
xxyyz
ghost
chips
demos
abCde
xxyyzz
hgost
chps
输出
good aaaaa
good abcde
good xxyyz
good ghost
good chips
good demos
bad abCde
bad xxyyzz
bad hgost
bad chps
啊,好吧,它是一个有限集,所以你总是可以交替枚举它!这会在一个小的 perl REPL 中发出一种 "brute force" 的正则表达式:
#include <stdio.h>
int main(void) {
printf("while (<>) { if (/^(?:");
for (int a = 'a'; a <= 'z'; ++a)
for (int b = a; b <= 'z'; ++b)
for (int c = b; c <= 'z'; ++c) {
for (int d = c; d <= 'y'; ++d)
printf("%c%c%c%c[%c-z]|", a, b, c, d, d);
printf("%c%c%czz", a, b, c);
if (a != 'z' || b != 'z' || c != 'z') printf("|\n");
}
printf(")$/x) { print \"Match!\n\" } else { print \"No match.\n\" }}\n");
return 0;
}
现在:
$ gcc r.c
$ ./a.out > foo.pl
$ cat > data.txt
aaaaa
abcde
xxyyz
ghost
chips
demos
abCde
xxyyzz
hgost
chps
^D
$ perl foo.pl < data.txt
Match!
Match!
Match!
Match!
Match!
Match!
No match.
No match.
No match.
No match.
正则表达式只有 220Kb 左右;-)
我最近遇到了一个难题,要找到匹配的正则表达式:
5-character-long strings comprised of lowercase English letters in ascending ASCII order
有效示例包括:
aaaaa
abcde
xxyyz
ghost
chips
demos
无效示例包括:
abCde
xxyyzz
hgost
chps
我目前的解决方案很笨拙。我使用正则表达式:
(?=^[a-z]{5}$)^(a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*)$
它使用非消耗捕获组断言字符串长度为5,然后验证该字符串是否按顺序由小写英文字母组成(see Rubular)。
相反,我想在字符 classes 中使用反向引用。类似于:
^([a-z])([-z])([-z])([-z])([-z])$
我脑海中的解决方案(see Rubular)的逻辑是捕获第一个字符[a-z],将其用作第二个字符class中的反向引用,依此类推。但是,</code>、<code>
...字符 classes 似乎指的是 ASCII 值 1、2...有效匹配任何四或五个字符的字符串。
我有两个问题:
- 我可以在角色 classes 中使用反向引用来检查升序字符串吗?
- 这个难题有没有更简单的解决方案?
我将此答案作为评论而不是答案发布,因为它的格式比评论更好。
与您的问题相关:
- Can I use back references in my character classes to check for ascending order strings?
不,你不能。如果您查看 backref regular-expressions 部分,您将找到以下文档:
Parentheses and Backreferences Cannot Be Used Inside Character Classes
Parentheses cannot be used inside character classes, at least not as metacharacters. When you put a parenthesis in a character class, it is treated as a literal character. So the regex [(a)b] matches a, b, (, and ).
Backreferences, too, cannot be used inside a character class. The in a regex like (a)[b] is either an error or a needlessly escaped literal 1. In JavaScript it's an octal escape.
关于你的第二个问题:
- Is there any less-hacky solution to this puzzle?
恕我直言,你的正则表达式非常好,你可以像这样在开始时将它缩短一点:
(?=^.{5}$)^a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*$
^--- Here
如果您愿意使用 Perl (!),这将有效:
/^([a-z])((??{"[-z]"}))((??{"[-z]"}))((??{"[-z]"}))(??{"[-z]"})$/
由于有人使用 Perl 打破僵局,所以这是一个
我猜 Perl 解决方案 ..
请注意,这是一个基本的非正则表达式解决方案,恰好是
塞入 Perl 正则表达式中的代码结构。
有趣的是,如果有一天你需要协同
regex/code 这是一个不错的选择。
那么有可能不是简单的 [a-z]
字符,而是
在它的位置使用非常复杂的模式并使用检查与最后。
那就是力量!!
正则表达式 ^(?:([a-z])(?(?{ $last gt })(?!)|(?{ $last = }))){5}$
Perl 代码
use strict;
use warnings;
$/ = "";
my @DAry = split /\s+/, <DATA>;
my $last;
for (@DAry)
{
$last = '';
if (
/
^ # BOS
(?: # Cluster begin
( [a-z] ) # (1), Single a-z letter
# Code conditional
(?(?{
$last gt # last > current ?
})
(?!) # Fail
| # else,
(?{ $last = }) # Assign last = current
)
){5} # Cluster end, do 5 times
$ # EOS
/x )
{
print "good $_\n";
}
else {
print "bad $_\n";
}
}
__DATA__
aaaaa
abcde
xxyyz
ghost
chips
demos
abCde
xxyyzz
hgost
chps
输出
good aaaaa
good abcde
good xxyyz
good ghost
good chips
good demos
bad abCde
bad xxyyzz
bad hgost
bad chps
啊,好吧,它是一个有限集,所以你总是可以交替枚举它!这会在一个小的 perl REPL 中发出一种 "brute force" 的正则表达式:
#include <stdio.h>
int main(void) {
printf("while (<>) { if (/^(?:");
for (int a = 'a'; a <= 'z'; ++a)
for (int b = a; b <= 'z'; ++b)
for (int c = b; c <= 'z'; ++c) {
for (int d = c; d <= 'y'; ++d)
printf("%c%c%c%c[%c-z]|", a, b, c, d, d);
printf("%c%c%czz", a, b, c);
if (a != 'z' || b != 'z' || c != 'z') printf("|\n");
}
printf(")$/x) { print \"Match!\n\" } else { print \"No match.\n\" }}\n");
return 0;
}
现在:
$ gcc r.c
$ ./a.out > foo.pl
$ cat > data.txt
aaaaa
abcde
xxyyz
ghost
chips
demos
abCde
xxyyzz
hgost
chps
^D
$ perl foo.pl < data.txt
Match!
Match!
Match!
Match!
Match!
Match!
No match.
No match.
No match.
No match.
正则表达式只有 220Kb 左右;-)