关于正则表达式的问题

在精通正则表达式40页上有这么一个例子:
作者用^[+-]?[0-9]+(.[0-9]*)?$来匹配带符号,带小数的数字。
这倒是很简单的例子,但是作者的批注我就没看懂了:
作者说(.[0-9]*)?和.?[0-9]*是截然不同的,对后一个表达式,即使.无法匹配,[0-9]*也能匹配接下来的数字。
我确实没看懂接下来匹配数字会有什么问题。
请指教,最好能给我个例子可以指出什么情况下这两个表达式匹配结果不同。
先谢。
[b]问题补充:[/b]
感谢Rowen和pan_java的回答,但我认为二位没有看清楚我得问题。关于这两个表达式的语法我是能看懂的,我看不懂的是^[+-]?[0-9]+(.[0-9]*)?$和^[+-]?[0-9]+.?[0-9]*$这个两个表达式有什么不同。请回答的时候注意:[color=red][b]最好能给我个例子可以指出什么情况下这两个表达式匹配结果不同[/b][/color]
[b]问题补充:[/b]
谢谢,pan_java,若以分组而论,这两个表达式确实不同,不过作者在这里完全没有提及分组,我敲一段原文,给大家看看:
作者在上一段讲了一个例子说用^[0-9]+$来匹配一个数字,
下面是这段的原文:
让我们扩展这个例子,允许输入负数和可能出现的小数部分。我们添加一个-?来容许最前面的负数符号。实际上,我们可以用[-+]来处理开头的正负号。
要容许可能出现的小数部分,我们添加(.[0-9]*)?。转义的点号匹配小数点,所以.[0-9]*用来匹配小数点和后面可能出现的数字。因为.[0-9]*被()?所包围,整个子表达式都不是匹配成果必须的([color=red]请注意,它与.?[0-9]*是截然不同的,对后一个表达式中,即使.无法匹配,[0-9]也能匹配接下来的数字[/color])。就是上边标红的这句话让我费解。
从作者行文看,这里是一个很简单的例子,应该不会说分组的东西。除了分组还有什么不同呢?
[b]问题补充:[/b]
pan_java, rowen:
看了二位最后的回复,我想可能是我把作者的意思搞错了。
我确认一下,二位觉得是不是作者在说.[0-9]*和(.[0-9]*)?这两个表达式的结果不同,[color=red]而不是说整个表达式即:^[+-]?[0-9]+(.[0-9]*)?$和^[+-]?[0-9]+.?[0-9]*$不同[/color]。如果这样的话,那我完全同意。
我其实疑惑的是^[+-]?[0-9]+(.[0-9]*)?$和^[+-]?[0-9]+.?[0-9]*$这两个表达式的匹配结果除了分组以外,有没有不同,二位觉得呢?
[b]问题补充:[/b]
ok,那么做结论。看来我提了一个比较傻的问题。鉴于pan_java指出有关于分组的不同,采纳pan_java的意见为答案。请其余的同学勿怪。谢谢大家的回答。

[code="java"]import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    String regexp1 = "^[+-]?[0-9]+(\\.[0-9]*)?$";
    String regexp2 = "^[+-]?[0-9]+\\.?[0-9]*$";

    Pattern pattern1 = Pattern.compile(regexp1);

    Pattern pattern2 = Pattern.compile(regexp2);

    String str = "0.36";

    Matcher m1 = null;

    Matcher m2 = null;

    m1 = pattern1.matcher(str);

    m2 = pattern2.matcher(str);


    //regexp1 对比 regexp2 主要是有一个分组的功能
    if(m1.find()){
        System.out.println(m1.group(0));//0.36
        System.out.println(m1.group(1));//.36
    }

    if(m2.find()){
        System.out.println(m2.group(0));//0.36

        //System.out.println(m2.group(1));//null
    }


}

}[/code]

[quote]作者说(.[0-9]*)?和.?[0-9]*是截然不同的,对后一个表达式,即使.无法匹配,[0-9]*也能匹配接下来的数字。[/quote]

这个很简单,说明一下就行了..
1. ?是0或1个的意思
(.[0-9]*)?是匹配0或1个(.[0-9]*),注意?之前的.[0-9]*在括号中,所以是整个括号里的内容匹配0或1次..
2. .?[0-9]*
.?是.出现的次数是0或1.所以即使.无法匹配,即出现0次,则可以继续匹配[0-9]*

.?[0-9]* 中的 .? 0个到1个. (?表示0到1)

有()的可以分1个以上的组,拿出匹配的,
而没有()的只有一个组.

因为.[0-9]*被()?所包围,整个子表达式都不是匹配成果必须的.
[color=red]解释这句话,相信你已经理解了.[/color]

请注意,它与.?[0-9]*是截然不同的,对后一个表达式中,即使.无法匹配,[0-9]也能匹配接下来的数字

对后一个表达式中--->是不是指.?[0-9]*

[color=red]即使.无法匹配[/color] 后面不是有一个问号吗?(?表示0到1个)
[color=red][0-9]也能匹配接下来的数字[/color]前面成功不影响后面的啊.

不知有没有清楚.

[quote]关于这两个表达式的语法我是能看懂的,我看不懂的是^[+-]?[0-9]+(.[0-9]*)?$和^[+-]?[0-9]+.?[0-9]*$这个两个表达式有什么不同。请回答的时候注意:最好能给我个例子可以指出什么情况下这两个表达式匹配结果不同[/quote]
?

还是给个例子吧:以(.[0-9]*)?和.?[0-9]*为准:
如果字符串是121234325
则(.[0-9]*)?就不能匹配.
而.?[0-9]*则能匹配...
现在懂了吗?
因为(.[0-9]*)?必须匹配. 也就是 带符号+1234
而.?[0-9]*则不是必须的也就是可以匹配14141241,也可以匹配 带符号+1234

(.[0-9]*)? 前面必须要有., .表示必须有.,然后再是[0-9]*,再把它看成(.[0-9]*),外面的问号再表示这个整体0或者1个.
.?[0-9]* 分成 .? 和[0-9]*

(.[0-9]*)?
( . [0-9]* ) ? ()表示一个整体

.?[0-9]*

.? 0-9]*
分开看会清晰很多

[quote]我其实疑惑的是^[+-]?[0-9]+(.[0-9]*)?$和^[+-]?[0-9]+.?[0-9]*$这两个表达式的匹配结果除了分组以外,有没有不同,二位觉得呢?[/quote]
没有,就分组不同而己...之前^[+-]?[0-9]+只是附加进去,匹配用的..后面才是不同的地方...

你理解上面我给的这个例子就差不多了,分组是这么定义的:用一系列括号包围一系列字符,字符类以及量词来使用...
分组是使用
比如:
var reDogDog =/dog/dog/g
用了分组可以这么写...
var reDogDog =/(dog){2}/g
var reg1 =/(dog)?/; 0或1个
var reg2 ==/(dog)*/; 0或多个

其实我下面这个例子就并不多说明了..
[quote]例子:以(.[0-9]*)?和.?[0-9]*为准:
如果字符串是121234325
则(.[0-9]*)?就不能匹配.
而.?[0-9]*则能匹配...
现在懂了吗?
因为(.[0-9]*)?必须匹配. 也就是 带符号+1234
而.?[0-9]*则不是必须的也就是可以匹配14141241,也可以匹配 带符号+1234 [/quote]

[quote]看了二位最后的回复,我想可能是我把作者的意思搞错了。[/quote]
我觉得是你想多了,作者说的我觉得还是很清楚的...
[quote]作者说(.[0-9]*)?和.?[0-9]*是截然不同的,对后一个表达式,即使.无法匹配,[0-9]*也能匹配接下来的数字。[/quote]

我看也是LZ想多了。作者没说两个大表达式有什么不同,只是说两个小表达式不同。大概在提示你匹配有符号小数时不能用.?[0-9]*