为什么这个先行断言在 Java 中不起作用?
我来自 Perl 背景,习惯于执行如下操作来匹配字符串中的前导数字并执行就地增量加一:
my $string = '0_Beginning';
$string =~ s|^(\d+)(?=_.*)|$1+1|e;
print $string; # '1_Beginning'
由于我对 Java 的了解有限,事情并不是那么简洁:
String string = "0_Beginning";
Pattern p = Pattern.compile( "^(\\d+)(?=_.*)" );
String digit = string.replaceFirst( p.toString(), "$1" ); // To get the digit
Integer oneMore = Integer.parseInt( digit ) + 1; // Evaluate ++digit
string.replaceFirst( p.toString(), oneMore.toString() ); //
正则表达式不'这里不匹配...但在 Perl 中却匹配。
我在这里做错了什么?
I come from a Perl background and am used to doing something like the following to match leading digits in a string and perform an in-place increment by one:
my $string = '0_Beginning';
$string =~ s|^(\d+)(?=_.*)|$1+1|e;
print $string; # '1_Beginning'
With my limited knowledge of Java, things aren't so succinct:
String string = "0_Beginning";
Pattern p = Pattern.compile( "^(\\d+)(?=_.*)" );
String digit = string.replaceFirst( p.toString(), "$1" ); // To get the digit
Integer oneMore = Integer.parseInt( digit ) + 1; // Evaluate ++digit
string.replaceFirst( p.toString(), oneMore.toString() ); //
The regex doesn't match here... but it did in Perl.
What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
其实很匹配。您可以通过打印来找
出问题是与行,
这实际上是一个什么也不做,因为它用第一组的内容替换了第一组(这是您匹配的所有内容,前瞻不是匹配的一部分)。
您可以通过以下代码获得所需的结果(即数字)。
注意:如果没有匹配的内容,您无论如何都应该检查
m.find()
。在这种情况下,您可能不会调用parseInt
并且会收到错误。因此完整的代码看起来像Actually it matches. You can find out by printing
The issue is with line
which is actually a do-nothing, because it replaces the first group (which is all you match, the lookahead is not part of the match) with the content of the first group.
You can get the desired result (namely the digit) via the following code
Note: you should check
m.find()
anyways if nothing matches. In this case you may not callparseInt
and you'll get an error. Thus the full code looks something like让我们看看你在这里做什么。
您声明并初始化 String 和模式对象。
(您将模式转换回字符串,replaceFirst 从中创建一个新模式。这是故意的吗?)
正如 Howard 所说,这会将字符串中模式的第一个匹配项替换为第一组的内容,并且模式的匹配在这里只是
0
,作为第一组。因此digit
等于string
,……并且您的解析在这里失败。
这可行(但将模式再次转换为字符串并返回模式)。
下面是我将如何做到这一点:(
当然,对于您的正则表达式,循环只会执行一次,因为正则表达式是锚定的。)
编辑:澄清我关于 string.replaceFirst 的声明:
此方法不返回一个模式,但在内部使用一个模式。 来自文档:
Here 完全相同的结果,我们看到从第一个参数编译了一个新模式。
这也向我们展示了另一种方法来完成您想做的事情:
这只编译模式一次,而不是像原始程序中那样编译三次 - 但仍然匹配两次(一次用于查找,一次用于
replaceFirst),而不是像我的程序中那样一次。
Let's see what you are doing here.
You declare and initialize String and pattern objects.
(You are converting the pattern back into a string, and replaceFirst creates a new Pattern from this. Is this intentional?)
As Howard says, this replaces the first match of the pattern in the string with the contents of the first group, and the match of the pattern is just
0
here, as the first group. Thusdigit
is equal tostring
, ...... and your parsing fails here.
This would work (but convert the pattern again to string and back to pattern).
Here how I would do this:
(Of course, for your regex the loop will only execute once, since the regex is anchored.)
Edit: To clarify my statement about string.replaceFirst:
This method does not return a pattern, but uses one internally. From the documentation:
Here we see that a new pattern is compiled from the first argument.
This also shows us another way to do what you did want to do:
This only compiles the pattern once, instead of thrice like in your original program - but still does the matching twice (once for find, once for
replaceFirst
), instead of once like in my program.