Java正则表达式中\\ 1 *运算符的含义

时间:2016-08-01 17:41:32

标签: java regex

我正在学习Java正则表达式,我注意到以下运算符:

import networkx as nx
G = nx.Graph()
G.add_nodes_from([1,3])
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(1,3)
G[1][2]['weight']=4400
G[2][3]['weight']=4100
G[1][3]['weight']=1500
print nx.betweenness_centrality(G,weight='weight')

我很难弄清楚它的含义(在网上搜索没有帮助)。 例如,这两个选项之间有什么区别:

\\*1

结果:

    Pattern p1 = Pattern.compile("(a)\\1*"); // option1
    Pattern p2 = Pattern.compile("(a)"); // option2

    Matcher m1 = p1.matcher("a");
    Matcher m2 = p2.matcher("a");

    System.out.println(m1.group(0));
    System.out.println(m2.group(0));

谢谢!

3 个答案:

答案 0 :(得分:5)

在这种情况下,

\\1是对应于此处(a)的第一个捕获组的返回引用。

因此(a)\\1*在此特定情况下等同于(a)a*

这是一个显示差异的例子:

Pattern p1 = Pattern.compile("(a)\\1*");
Pattern p2 = Pattern.compile("(a)");

Matcher m1 = p1.matcher("aa");
Matcher m2 = p2.matcher("aa");

m1.find();
System.out.println(m1.group());
m2.find();
System.out.println(m2.group());

<强>输出:

aa
a

正如您所看到的,当您有多个a时,第一个正则表达式捕获所有连续的a,而第二个正则表达式仅捕获第一个正则表达式。

答案 1 :(得分:3)

a再次查找(a)\\1+次,0次或更多次。也许这个例子更容易理解,使用a,它会查找至少2 Pattern p1 = Pattern.compile("(a)\\1+"); Matcher m1 = p1.matcher("aaaaabbaaabbba"); while (m1.find()) System.out.println(m1.group()); s:

a

输出将是:

  

AAAAA
  AAA

但最后一次FATAL EXCEPTION: main Process: com.herprogramacin.hermosaprogramacion, PID: 14900 java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.herprogramacin.hermosaprogramacion.UI.Adapters.RVAdapter) at android.os.Parcel.writeSerializable(Parcel.java:1468) at android.os.Parcel.writeValue(Parcel.java:1416) at android.os.Parcel.writeArrayMapInternal(Parcel.java:686) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330) at android.os.Bundle.writeToParcel(Bundle.java:1079) at android.os.Parcel.writeBundle(Parcel.java:711) at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:137) at android.os.Parcel.writeTypedArray(Parcel.java:1254) at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:384) at android.os.Parcel.writeParcelable(Parcel.java:1437) at android.os.Parcel.writeValue(Parcel.java:1343) at android.os.Parcel.writeArrayMapInternal(Parcel.java:686) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330) at android.os.Bundle.writeToParcel(Bundle.java:1079) at android.os.Parcel.writeBundle(Parcel.java:711) at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3701) at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4622) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:158) at android.app.ActivityThread.main(ActivityThread.java:7224) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) Caused by: java.io.NotSerializableException: android.database.sqlite.SQLiteCursor at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344) at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959) at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360) at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054) at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384) at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461) at android.os.Parcel.writeSerializable(Parcel.java:1463) at android.os.Parcel.writeValue(Parcel.java:1416)  at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)  at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)  at android.os.Bundle.writeToParcel(Bundle.java:1079)  at android.os.Parcel.writeBundle(Parcel.java:711)  at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:137)  at android.os.Parcel.writeTypedArray(Parcel.java:1254)  at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:384)  at android.os.Parcel.writeParcelable(Parcel.java:1437)  at android.os.Parcel.writeValue(Parcel.java:1343)  at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)  at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)  at android.os.Bundle.writeToParcel(Bundle.java:1079)  at android.os.Parcel.writeBundle(Parcel.java:711)  at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3701)  at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4622)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:158)  at android.app.ActivityThread.main(ActivityThread.java:7224)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)  赢了,因为它没有重复。

答案 2 :(得分:1)

  

在Perl中,\ 1到\ 9始终被解释为后引用;如果存在至少那么多子表达式,则将大于9的反斜杠转义数视为后引用,否则如果可能,将其解释为八进制转义。在这个类中,八进制转义必须始终以零开头。在此类中,\ 1到\ 9始终被解释为后引用,如果正则表达式中的那个点至少存在多个子表达式,则接受较大的数字作为后引用,否则解析器将丢弃数字直到该数字小于或等于现有的组数或一个数字。

来自Pattern文档。

所以看起来p2只对一个"a"有用,而p1对任意数量的"a"都有好处,只要至少有一个X* X, zero or more times。明星是$(this).parent('ul').slideToggle(400); 。它被称为Kleene星。