匹配除单个数字外的所有内容的正则表达式。

3
匹配单个数字以外的所有内容的正则表达式是什么?例如,stack应该匹配,stack overflow也应该匹配,12389237应该匹配,但2不应该匹配。我使用了^[^\d]+$,但显然它不能满足我的第三个条件。
编辑:顺便说一下,这是为PHP准备的。

2
它是否应该匹配空字符串,因为那也不是单个数字? - Kaivosukeltaja
如果这是针对PHP的,为什么你要加上Perl标签? - TLP
@Kaivosukeltaja 好的,除了单个数字以外的任何东西。干杯。 - ObiHill
@TLP PHP 使用 PCRE(Perl-Compatible Regular Expressions),是吗?! - ObiHill
@ChuckUgwuh 添加 Perl 标签会使很多人困惑,特别是因为你的问题没有明确表明你正在寻找 PHP 解决方案。 - TLP
显示剩余2条评论
6个回答

4

将其分解为两种情况。要么匹配一个不是数字的单个字符,要么匹配长度大于等于2的任意字符串:

^(\D|.{2,})$

很抱歉,您误解了问题。 - tchrist
@tchrist:为什么?它似乎符合要求的标准。 - VeeArr
你的模式匹配了他的第四行,但这不应该发生。 - tchrist
1
不,它不会。我建议你试一下。 - VeeArr
2
@tchrist 我认为 OP 并不打算让注释成为匹配过程的一部分。 - TLP
显示剩余7条评论

2
最简单的方法是使用常规程序逻辑来否定匹配单个数字:
 ! /(?<!\d)\d(?!\d)/

将其编码为单个模式是可能的,但很烦人。
/^(?!.*(?<!\d)\d(?!\d))/

或通过/x进行传播:

/ ^ (?! .* (?<! \d) \d (?! \d) )/x

或者在各种多行情况下进行隔离:

 / \A (?! .* (?<! \d) \d (?! \d) )/sx

看到我为什么说否定一个正则表达式匹配更容易了吗?

这是测试程序:

use v5.12;
while (<DATA>) {
    my $got =  / ^ (?! .* (?<! \d) \d (?! \d) )/x;
    print $got ? "PASS" : "FAIL";
    print ": ", $_;

}
__END__
"stack" should match
"stack overflow" should match
"12389237" should match but
"2" should not match

这将会产生:

PASS: "stack" should match
PASS: "stack overflow" should match
PASS: "12389237" should match but
FAIL: "2" should not match

编辑

如果你的问题格式不正确,而且你只是想说这些字符串实际上是

stack
stack overflow
12389237
2

如果要实现这个功能,简单的方法是对单个数字进行否定匹配:

! /^\d$/

更加仔细的说,
! /\A\d\z/

将“not”操作集成到模式中从来都不是一件容易的事情。
/^ (?! \d $ )/x

这是另一个测试程序:

use v5.12;
while (<DATA>) {
    my $got =  /^ (?! \d $ )/x;
    print $got ? "PASS" : "FAIL";
    print ": $_";

}
__END__
stack
stack overflow
12389237
2

报告显示:

PASS: stack
PASS: stack overflow
PASS: 12389237
FAIL: 2

“\z”与“$”的区别比“\A”与“^”更重要;据我所知,后者只有在将字符串正则表达式片段插入/m上下文中时才会有所不同。 - ysth
1
@ysth 哎呀,不再这样了。即使面对一个覆盖词法作用域的 use re "/msx" 语法规则,也必须保证正确的行为。 - tchrist
谢谢。听起来够用了 :) - ysth

2

不匹配单个数字,反向匹配:

!/^\d\z/

或者使用负向先行断言进行正则表达式匹配:

/^(?!\d\z)/

你可能想使用\Z$。否则,+1,因为这正是我要发布的内容。 - TLP
如果你想在字符串结尾之前允许换行(例如 "2\n"),你可以使用 $\Z 而不是 \z - Qtax

1

一定要用正则表达式吗?对于 PHP,你可以这样做

is_integer($string) && $string < 10

1
Undefined subroutine &main::is_integer called at.. - TLP
抱歉,仅适用于 PHP 而非 Perl。 - safarov
这不是一个坏主意,只是不适用于 Perl 解决方案。 - TLP
+1 看起来你的答案现在是有效的,因为OP说它是用于PHP的。 - TLP

0
以下正则表达式将匹配一个字符串(包括空格),以及任何不是单个数字的数字:
/^[a-zA-z\s]+|[0-9]{2,}$/gm

RegExr 代码


1
那不会在他说应该的东西上起作用。此外,没有理由将孤立的\D放在周围的方括号中。 - tchrist
我不确定你的 /g/m 有什么意义。你在想什么? - tchrist

0
while(my $line = <DATA>){
    chomp $line;
    if ($line !~ /^\d{1}$/) {
        print "$line    match\n";
    }
    else {
        print "$line    NOT match\n";
    }
}

__DATA__
stack
stack overflow
12389237
2

结果:

perl regex.pl
stack   match
stack overflow  match
12389237        match
2       NOT match

"{1}" 在所有方面都是多余的,除了明确表示。 - TLP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接