gpt4 book ai didi

java - 如何在Java中替换括号(),保留内容并制表符结果?

转载 作者:行者123 更新时间:2023-11-30 08:18:51 32 4
gpt4 key购买 nike

我想在使用制表符和添加换行符时替换字符串中的括号,就像 pretty-print 一样。

 (foo) AND ((bar) OR (baz))

变成了

     (
foo
)
AND
(
(
bar
)
OR
(
baz
)
)

我已经尝试过:

   "((foo) OR ((bar)(baz)))".replaceAll("\\((.*?)\\)", "\\(\n\t$1\n\\)")

但它不太有效。

最佳答案

laune azurefrog 有权利。您提供的表达式不是正则表达式,因此您无法使用正则表达式引擎来美化表达式。在我看来,你能做的最好的事情就是编写一个可以处理此任务的解析器。我总是试图将解析器逻辑与处理业务的代码分开。您可以注意到在 ExpressionListener 的实现中处理格式化席位的逻辑。您可以在下面找到代码。

public class PrettyPrintExample {

private interface ExpressionListener {

void lb();

void rb();

void content(String content);

}

private enum Type {
LB, RB, STRING, END
}

private static class Token {
Type type;
String value;

public Token(Type type, String value) {
super();
this.type = type;
this.value = value;
}

@Override
public String toString() {
return "Token [type=" + type + ", value=" + value + "]";
}
}

private static class Lexer {

private int current;
private String input;

public Lexer(String input) {
this.input = input;
}

private char getChar() {
return input.charAt(current++);
}

private void unputChar() {
current--;
}

private boolean hasNextChar() {
return current < input.length();
}

Token next() {

if (!hasNextChar()) {
return new Token(Type.END, "");
}

char c = getChar();

while (Character.isWhitespace(c)) {
c = getChar();
}

if (c == '(') {
return new Token(Type.LB, "(");
}

if (c == ')') {
return new Token(Type.RB, ")");
}

unputChar();

StringBuilder buffer = new StringBuilder();
while (hasNextChar()) {

c = getChar();

if (c != '(' && c != ')' && !Character.isWhitespace(c)) {
buffer.append(c);
} else {
unputChar();
break;
}

}

return new Token(Type.STRING, buffer.toString());

}
}

private static Lexer lexer;
private static Token currentToken;

public static void parse(String line, ExpressionListener listener) {
lexer = new Lexer(line);
currentToken = lexer.next();
expression(listener);
consume(Type.END);
}

private static void expression(ExpressionListener listener) {

while (true) {

if (match(Type.STRING)) {
listener.content(currentToken.value);
consume(Type.STRING);
} else if (match(Type.LB)) {
consume(Type.LB);
listener.lb();
expression(listener);
consume(Type.RB);
listener.rb();
} else {
break;
}

}

}

private static boolean match(Type type) {
return type == currentToken.type;
}

private static void consume(Type type) {
if (!match(type)) {
throw new RuntimeException(String.format("Should be %s is %s", type.name(), currentToken.type.name()));
}
currentToken = lexer.next();
}

public static void main(String[] args) {
String line = "(foo) AND ((bar) OR (baz))";
parse(line, new ExpressionListener() {

private int indent = 0;

private void indent(int indent) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < indent; i++) {
builder.append("\t");
}
System.out.print(builder.toString());
}

private void nl() {
System.out.println();
}

@Override
public void lb() {
indent(++indent);
System.out.print("(");
nl();
}

@Override
public void rb() {
indent(indent);
System.out.print(")");
indent--;
nl();
}

@Override
public void content(String content) {
indent(indent);
System.out.print(content);
nl();
}
});

}

}

输出

    (
foo
)
AND
(
(
bar
)
OR
(
baz
)
)

我知道针对您的情况使用 CFL 解析器并不是最简单的解决方案,但请注意,如果您的表达式变得非常复杂,那么扩展解析器将非常容易。

关于java - 如何在Java中替换括号(),保留内容并制表符结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29264150/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com