我是regex的新手。 我试图使用正则表达式为声纳Rule
重新排列方法访问修饰符(public|protected|private)|(abstract|static)|(final)|(volatile)|(synchronized)|(native)|(strictfp)
将输入示例作为
static public void main(String[] args)
,然后使用
$1$2$3$4$5$6$7
进行替换,但我得到的结果相同。
输出应该按照正确的访问修饰符顺序排列,例如第一个public,然后是static:
public static void main (String[] args)
方法签名应遵循顺序:
public or protected or private
,然后(如果适用)
abstract or static
,然后(如果适用)
final
,然后(如果适用)
volatile
,然后(如果适用)
synchronized
,然后(如果适用)
native
,然后(如果适用)
stictfp
答案 0 :(得分:3)
问题是您的(…)|(…)|(…)|…
格式的模式指定了替代项,而只有一个必须匹配。因此,您的模式一次只匹配一个关键字,一组包含匹配关键字,而所有其他组均为空。然后,当您将匹配项替换为$1$2$3$4$5$6$7
时,您将关键字替换为自身,其他组则没有任何效果。重复应用该操作仍然无效。
因此,您需要一种与关键字的整个序列匹配的模式,以填充存在关键字的组。为此,请使用+
量词将正则表达式包含在另一组中,以匹配至少一个关键字,但要与存在的关键字一样多。重复组中的捕获组的好处是,如果它们在下一个重复中不匹配,则他们会记住自己的前一场比赛。因此,在确定重复组的匹配项之后,如果序列中有一个,则每个子组都捕获了一个关键字。
因此生成的模式看起来像
(?:\b((?:public|protected|private)\s+)|((?:abstract|static)\s+)|(final\s+)|((?:volatile|synchronized)\s+)|((?:native|strictfp)\s+))+
在这里,我确定了更多的互斥关键字,将数量减少到了五个组。我在组中包括了后续的空格(使用类似((?:keyword1|keyword2)\s+)
的子模式,在非捕获组中列出了替代项)。这样,替换中将有正确的间距。我在开头(\b
)处添加了一个单词边界,以确保没有错误的匹配(例如单词nonstatic
)。由于必须使用空格,因此已经暗示了关键字后的单词边界。
在Java代码中:
String in = "synchronized public final static native void main(String[] args)";
String out = in.replaceAll(
"(?:\\b"
+ "((?:public|protected|private)\\s+)|((?:abstract|static)\\s+)|"
+ "(final\\s+)|((?:volatile|synchronized)\\s+)|((?:native|strictfp)\\s+)"
+ ")+",
"$1$2$3$4$5"
);
System.out.println(out);// public static final synchronized native void main(String[] args)
但是请注意,这有局限性。对于Java语言,注释是修饰符,因此可以与关键字修饰符自由混合,例如, static @Deprecated public
。由于注释具有递归语法(注释可能包含注释,但是即使是更简单的情况(例如嵌套常量表达式或数组初始化程序)也可能具有不同的深度),因此无法通过单个正则表达式解析所有有效注释值。因此,以上解决方案仅处理关键字,并且无论您可能添加多少注释案例,您都必须在某处进行切入,考虑其他所有不支持的内容。
答案 1 :(得分:-1)
您所拥有的基本上就是您所需要的,您只需要将各个部分放在一起。正则表达式应为
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="false"
app:contentPadding="0dp"
app:contentPaddingBottom="0dp"
捕获组索引是确定应该去哪里的内容。如果您可以捕获整个方法签名,即。
(public|protected|private)|(abstract|static)|(final)|(volatile)|(synchronized)|(native)|(strictfp)
作为字符串,则上面的正则表达式将在捕获组1中捕获static public void main(String[] args)
,在捕获组2中捕获public
。Try it out here!
使用java.util.regex。{Pattern,Matcher}获取捕获组,然后手动重新排列捕获组,确保使用String.trim()删除多余的空格。
这是一个可行的解决方案
static
示例输出:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Signature {
public static void main(String[] args) {
// slightly more complex example to show off capabilities of method
String oldSignature = "synchronized static final native public void barFooer(int foo, double bar)";
// echo to user
System.out.printf("%nOriginal method signature:%n %s%n%n", oldSignature);
// group number ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ( 6 ) ( 7 )
String regex = "(public|protected|private)|(abstract|static)|(final)|(volatile)|(synchronized)|(native)|(strictfp)";
// create regex.Pattern and regex.Matcher objects
Pattern pat = Pattern.compile(regex);
Matcher mat = pat.matcher(oldSignature);
// array to hold signature "groups" in correct order
String[] groups = new String[7];
// int to hold end of last matched group
int endOfLastGroup = -1;
while (mat.find()) {
for (int gg = 1; gg <= 7; ++gg) {
// get the new matched group and any previous match in this group
String newGroup = mat.group(gg);
String oldGroup = groups[gg-1];
// where does the new matched group end?
int endOfNewGroup = mat.end();
// did we find a new match in this group?
if (newGroup != null) {
// cannot have, for instance, both "public" and "private"
if (oldGroup != null) {
System.err.printf("Error! Signature cannot contain both '%s' and '%s'!%n", newGroup.trim(), oldGroup.trim());
return;
}
// otherwise, new group found!
groups[gg-1] = newGroup;
// find furthest-right matched group end
if (mat.end() > endOfLastGroup)
endOfLastGroup = mat.end();
} } }
// new signature will be constructed with a StringBuilder
StringBuilder newSignature = new StringBuilder("");
// add groups to new signature in correct order
for (String group : groups) {
if (group != null) {
newSignature.append(group.trim());
newSignature.append(" ");
} }
// finally, add the return type, method name, arguments, etc.
newSignature.append(oldSignature.substring(endOfLastGroup).trim());
// echo to user
System.out.printf("New method signature:%n %s%n%n", newSignature.toString());
}
}
以下要点也提供此代码: https://gist.github.com/awwsmm/85575d2756f69b95564ff11b8ee105fd