我有一个正则表达式来匹配人名。
到目前为止,我有^([a-zA-Z \'\ s] +)$但是id喜欢添加一个检查以允许最多4个空格。我如何修改它来做到这一点?
编辑:我的意思是字符串
中的任意位置有4个空格答案 0 :(得分:11)
不要尝试正则表达式验证名称。人们可以随心所欲地打电话给自己。这可以包括任何字符。仅仅因为你住在只使用英语的地方并不意味着所有使用你系统的人都会有英文名字。我们甚至不得不在我们的系统Unicode中创建名称字段。它是数据库中唯一的Unicode类型。
如果您在意,我们实际上将名称拆分为“”,并将每个名称部分存储为单独的记录,但我们有一些非常具体的要求,这意味着这是一个好主意。
PS。我的妈妈的名字有5个空格。
答案 1 :(得分:6)
^ # Start of string
(?!\S*(?:\s\S*){5}) # Negative look-ahead for five spaces.
([a-zA-Z\'\s]+)$ # Original regex
或者在一行中:
^(?!(?:\S*\s){5})([a-zA-Z\'\s]+)$
如果字符串中有五个或更多空格,则五个将与否定前瞻匹配,并且整个匹配将失败。如果有四个或更少,原始正则表达式将匹配。
答案 2 :(得分:5)
在这里使用正则表达式似乎正在为解决方案创建问题,而不仅仅是解决问题。
即使是新手程序员,这项任务应该“容易”,正则表达式的新思想已经污染了我们的思想!
1: Get Input
2: Trim White Space
3: If this makes sence, trim out any 'bad' characters.
4: Use the "split" utility provided by your language to break it into words
5: Return the first 5 Words.
火箭科学。
你是什么意思搞这个正则表达式?你显然是VB程序员。 正则表达式是使用字符串的最有效方法。学习它们。
没有。 Php,玩弄了一点红宝石,现在变成了perl。
有一些东西(比如这种情况),基于正则表达式的替代方案在计算上和逻辑上指数过于复杂。
我用正则表达式解析整个php源文件,我不是他们使用的新手。
但是有很多情况,比如这个,你雇用一家伐木公司来修剪你的玫瑰丛。
我当然可以用正则表达式执行所有步骤2到5,但它们将是简单的原子正则表达式,没有奇怪的回溯语法或递归搜索的可能性。
上面列出的步骤1到5具有已知的范围,已知的输入范围,并且它的功能没有模糊性。至于你的正则表达式,你必须得到别人的贡献才能写出如此简单的事实证明了这一点。
我看到有人认为我的帖子很冒犯,我有点不高兴我不能说这个事实对我来说是冒犯的。 ;)
布丁证明:
sub getNames{
my @args = @_;
my $text = shift @args;
my $num = shift @args;
# Trim Whitespace from Head/End
$text =~ s/^\s*//;
$text =~ s/\s*$//;
# Trim Bad Characters (??)
$text =~ s/[^a-zA-Z\'\s]//g;
# Tokenise By Space
my @words = split( /\s+/, $text );
#return 0..n
return @words[ 0 .. $num - 1 ];
} ## end sub getNames
print join ",", getNames " Hello world this is a good test", 5;
>> Hello,world,this,is,a
如果对任何人有任何模棱两可的含义,我会很乐意向他们解释。注意到我还在使用regexp。其他语言我会尽可能使用他们原生的“修剪”功能。
我首先尝试了这种方法。这是关于正则表达式的大脑。孩子们,不要做正则表达式。
这可能是一个好的开始
/([^\s]+
(\s[^\s]+
(\s[^\s]+
(\s[^\s]+
(\s[^\s]+|)
|)
|)
|)
)/
(为清晰起见,为了破损)
/([^\s]+(\s[^\s]+(\s[^\s]+(\s[^\s]+|)|)|))/
(实际)
我在这里使用[^\s]+
而不是你的A-Z组合来表示苛刻,但重点在于嵌套的可选组
即:
(Hello( this( is( example))))
(Hello( this( is( example( two)))))
(Hello( this( is( better( example))))) three
(Hello( this( is()))))
(Hello( this()))
(Hello())
(注意:这一点虽然令人费解,但它的好处是可以将每个名称与自己的组相匹配)
如果您想要可读代码:
$word = '[^\s]+';
$regex = "/($word(\s$word(\s$word(\s$word(\s$word|)|)|)|)|)/";
(它围绕着“得到这个,或什么也得不到”的(捕捉|)咒语)
答案 3 :(得分:3)
答案 4 :(得分:2)
^([a-zA-Z']+\s){0,4}[a-zA-Z']+$
这假设你想要里面这个字符串的4个空格(即你已经修剪过它)
编辑:如果你想在任何地方使用4个空格我建议你不要使用正则表达式 - 你最好使用substr_count
(或者用你的语言中的等价物)。
我也同意pipTheGeek的说法有很多种不同的写名方式,你可能最好不要相信用户正确的名字(虽然我发现很多人都不打扰使用大写字母电子商务结帐)。
答案 5 :(得分:2)
以下是您最有可能寻找的答案:
^[a-zA-Z']+(\s[a-zA-Z']+){0,4}$
那说(英文):“从头到尾,匹配一个或多个字母,还可以有一个空格,然后是另一个'名字',最多四次。”
BTW:你为什么要让他们在名字的任何地方都有撇号?
答案 6 :(得分:-1)
匹配多个空格,后跟行尾的两个字符。
相关问题----
从字符串中删除前面带有多个空格的尾随2个字符...例如,如果列包含此字符串 - “'这是一个长串,在AB末端有2个字符” 然后,AB应该在保留句子的同时删除。
解决方案----
select 'This is a long string with 2 chars at the end AB' as "C1",
regexp_replace('This is a long string with 2 chars at the end AB',
'[[[:space:]][a-zA-Z][a-zA-Z]]*$') as "C2" from dual;
输出----
C1
This is a long string with 2 chars at the end AB
C2
This is a long string with 2 chars at the end
分析---- 正则表达式指定 - 匹配并替换空格([:space:])的零个或多个出现(*),然后在结尾处组合两个字符([a-zA-Z] [a-zA-Z])这条线。
希望这很有用。