codingBat repeatEnd使用正则表达式 [英] codingBat repeatEnd using regex
问题描述
我正在尝试尽可能多地了解正则表达式,所以我想出了这个基于正则表达式的解决方案 codingbat.com repeatEnd
:
I'm trying to understand regex as much as I can, so I came up with this regex-based solution to codingbat.com repeatEnd
:
给定一个字符串和一个int N,返回由N个重复的字符串的最后N个字符组成的字符串。您可以假设N介于0和字符串的长度之间(包括0和字符串)。
Given a string and an int N, return a string made of N repetitions of the last N characters of the string. You may assume that N is between 0 and the length of the string, inclusive.
public String repeatEnd(String str, int N) {
return str.replaceAll(
".(?!.{N})(?=.*(?<=(.{N})))|."
.replace("N", Integer.toString(N)),
"$1"
);
}
部分说明:
-
。(?!。{N})
:确认匹配的字符是最后N个字符之一,确保它后面没有N个字符。 -
(?=。*(?< =(。{N})))
:在这种情况下,使用lookforward首先一直到字符串的结尾,然后使用嵌套的lookbehind将最后N个字符捕获到\1
。请注意,此断言将始终为真。
.(?!.{N})
: asserts that the matched character is one of the last N characters, by making sure that there aren't N characters following it.(?=.*(?<=(.{N})))
: in which case, use lookforward to first go all the way to the end of the string, then a nested lookbehind to capture the last N characters into\1
. Note that this assertion will always be true.
|。
:如果第一个断言失败(即前面至少有N个字符然后然后匹配字符; \1
将为空。
|.
: if the first assertion failed (i.e. there are at least N characters ahead) then match the character anyway; \1
would be empty.
在任何一种情况下,字符始终匹配;用 \1
替换它。
In either case, a character is always matched; replace it with \1
.
我的问题是:
- 这种嵌套断言技术是否有效? (即在前瞻期间向后看?)
- 是否有更简单的基于正则表达式的解决方案?
执行 repeatBegin
(如类似定义) 。
Do repeatBegin
(as analogously defined).
我老实说这个问题很麻烦!
I'm honestly having troubles with this one!
推荐答案
好一个!虽然我会重构它以避免不必要地使用负逻辑,但我没有看到显着改进该正则表达式的方法:
Nice one! I don't see a way to significantly improve on that regex, although I would refactor it to avoid the needless use of negative logic:
".(?=.{N})|.(?=.*(?<=(.{N})))"
这样,在你到达最终的 N 字符之前,永远不会输入第二种选择,我认为这意味着意图更加清晰。
This way the second alternative is never entered until you reach the final N characters, which I think makes the intent a little clearer.
我从来没有看到一个参考文献说它可以嵌套外观,但就像巴特一样,我不明白为什么它不会。我有时会在lookbehinds中使用lookaheads来绕过可变长度lookbehind表达式的限制。
I've never seen a reference that says it's okay to nest lookarounds, but like Bart, I don't see why it wouldn't be. I sometimes use lookaheads inside lookbehinds to get around limitations on variable-length lookbehind expressions.
编辑:我刚刚意识到我可以通过将更改放在前瞻中来简化正则表达式:
I just realized I can simplify the regex quite a bit by putting the alternation inside the lookahead:
".(?=.{N}|.*(?<=(.{N})))"
顺便说一句,您是否考虑使用 format()
来构建正则表达式而不是 replace()
?
By the way, have you considered using format()
to build the regex instead of replace()
?
return str.replaceAll(
String.format(".(?=.{%1$d}|.*(?<=(.{%1$d})))", N),
"$1"
);
这篇关于codingBat repeatEnd使用正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!