我怀疑这已经在某处得到了解答,但我找不到它,所以......
我需要从一个更大的字符串中的两个标记之间提取一个字符串,其中第二个标记可能会再次出现... ...(伪代码...)
myString = "A=abc;B=def_3%^123+-;C=123;" ;
myB = getInnerString(myString, "B=", ";" ) ;
method getInnerString(inStr, startToken, endToken){
return inStr.replace( EXPRESSION, "$1");
}
所以,当我使用表达式“.+B=(.+);.+
”运行时
我得到“def_3%^ 123 + - ; C = 123;”大概是因为它只是寻找';'的最后一个例子在字符串中,而不是停在第一个字符串中。
我尝试使用(?=)搜索第一个';'但它给了我相同的结果。
我似乎找不到一个regExp引用来解释如何指定“NEXT”令牌而不是最后一个令牌。
任何和所有帮助都非常感谢。
关于SO的类似问题:
答案 0 :(得分:7)
您使用的是贪婪模式,但未在其中指定?
。试试这个:
".+B=(.+?);.+"
答案 1 :(得分:5)
试试这个:
B=([^;]+);
这符合B=
和;
之间的所有内容,除非它是;
。因此,它会匹配B=
与之后的第一个;
之间的所有内容。
答案 2 :(得分:2)
(这是评论与Evan回答的对话的延续。)
以下是应用(更正的)正则表达式时会发生的情况:首先,.+
匹配整个字符串。然后它回溯,放弃它刚刚匹配的大部分字符,直到它到达B=
可以匹配的点。然后(.+?)
匹配(并捕获)它看到的所有内容,直到下一部分(分号)匹配。然后最后的.+
吞噬剩下的角色。
你真正感兴趣的是“B =”和“;”以及它们之间的任何内容,为什么要匹配其余的字符串呢?您必须这样做的唯一原因是您可以用捕获组的内容替换整个字符串。但是,如果您可以直接访问该组的内容,为什么还要这么做呢?这是一个演示(在Java中,因为我不知道你正在使用什么语言):
String s = "A=abc;B=def_3%^123+-;C=123;";
Pattern p = Pattern.compile("B=(.*?);");
Matcher m = p.matcher(s);
if (m.find())
{
System.out.println(m.group(1));
}
为什么在'发现'这么简单的情况下'替换'?可能是因为您的API更容易;这就是我们用Java做的原因。 Java在其String类中有几个面向正则表达式的便捷方法:replaceAll()
,replaceFirst()
,split()
和matches()
(如果正则表达式匹配,则返回true
整个字符串),但不是find()
。并且也没有用于访问捕获组的便捷方法。我们无法与Perl单行的优雅相匹敌:
print $1 if 'A=abc;B=def_3%^123+-;C=123;' =~ /B=(.*?);/;
...所以我们满足于这样的黑客:
System.out.println("A=abc;B=def_3%^123+-;C=123;"
.replaceFirst(".+B=(.*?);.+", "$1"));
为了清楚起见,我并不是说不要使用这些黑客,或者说Evan的回答有什么问题 - 没有。我认为我们应该理解为什么我们使用它们,以及我们在做什么时做出的权衡。