Java 用一些规则替换嵌套字符串
字符串中有3条规则:Java 用一些规则替换嵌套字符串,java,parsing,syntax,nested,stack,Java,Parsing,Syntax,Nested,Stack,字符串中有3条规则: 它包含单词或组(用括号括起来),组可以嵌套 如果单词或组之间有空格,则这些单词或组应附加“+” 例如: "a b" needs to be "+a +b" "a (b c)" needs to be "+a +(+b +c)" "aa|bb|(cc|(ff gg)) hh" needs to be "+(aa bb (cc (+ff +gg))) +hh" 如果单词或组之间有一个|,则这些单词或组应该用括号括起来。 例如: 考虑所有规则,下面是另一个示例: "a b"
"a b" needs to be "+a +b"
"a (b c)" needs to be "+a +(+b +c)"
"aa|bb|(cc|(ff gg)) hh" needs to be "+(aa bb (cc (+ff +gg))) +hh"
|
,则这些单词或组应该用括号括起来。
例如:"a b" needs to be "+a +b"
"a (b c)" needs to be "+a +(+b +c)"
"aa|bb|(cc|(ff gg)) hh" needs to be "+(aa bb (cc (+ff +gg))) +hh"
我曾尝试使用regex、stack和,但仍然无法完全解决这个问题
任何人都可以分享这个问题的逻辑或伪代码吗
新编辑:
还有一条更重要的规则:竖条具有更高的优先级
例如:
aa | bb hh cc | dd(a | b)
需要是+(aa bb)+hh+(cc dd)+(a b))
(aa-dd)| bb | cc(ee-ff)|(gg-hh)
需要是+(+aa+dd)bb-cc+(+ee+ff)(+gg+hh))
新编辑:
为了解决优先级问题,我找到了一种在调用Sunil Dabburi的方法之前添加括号的方法
例如:
aa | bb hh cc | dd(a | b)
将是(aa | bb)hh(cc | dd)(a | b)
(aa-dd)| bb | cc(ee-ff)|(gg-hh)
将是((aa-dd)| bb | cc)((ee-ff)|(gg-hh))
因为性能对我的应用程序来说不是一个大问题,所以这种方式至少可以让它对我起作用。我想JavaCC工具可以很好地解决这个问题。希望其他人能继续讨论并提出这个问题。我试图解决这个问题。不确定它是否在所有情况下都有效。通过问题中给出的输入进行验证,结果良好
。现在左侧部分
可以为空,类似的右侧部分
可以为空。我们需要处理这些案件。
此外,如果右侧部分
以空格开头,我们需要根据空格要求向左侧部分
添加“+”
注意:我不确定对(a | b)
的期望是什么。如果结果应该是((a b))
或(a b)
。我将纯粹根据它的定义来使用((a b))
下面是工作代码:
public class Test {
public static void main(String[] args) {
String input = "aa|bb hh cc|dd (a|b)";
String result = formatSpaces(formatPipes(input)).replaceAll("\\$", " ");
System.out.println(result);
}
private static String formatPipes(String input) {
while (true) {
char[] chars = input.toCharArray();
int pIndex = input.indexOf("|");
if (pIndex == -1) {
return input;
}
input = input.substring(0, pIndex) + '$' + input.substring(pIndex + 1);
int first = pIndex - 1;
int closeParenthesesCount = 0;
while (first >= 0) {
if (chars[first] == ')') {
closeParenthesesCount++;
}
if (chars[first] == '(') {
if (closeParenthesesCount > 0) {
closeParenthesesCount--;
}
}
if (chars[first] == ' ') {
if (closeParenthesesCount == 0) {
break;
}
}
first--;
}
String result;
if (first > 0) {
result = input.substring(0, first + 1) + "(";
} else {
result = "(";
}
int last = pIndex + 1;
int openParenthesesCount = 0;
while (last <= input.length() - 1) {
if (chars[last] == '(') {
openParenthesesCount++;
}
if (chars[last] == ')') {
if (openParenthesesCount > 0) {
openParenthesesCount--;
}
}
if (chars[last] == ' ') {
if (openParenthesesCount == 0) {
break;
}
}
last++;
}
if (last >= input.length() - 1) {
result = result + input.substring(first + 1) + ")";
} else {
result = result + input.substring(first + 1, last) + ")" + input.substring(last);
}
input = result;
}
}
private static String formatSpaces(String input) {
if (input.isEmpty()) {
return "";
}
int startIndex = input.indexOf("(");
if (startIndex == -1) {
if (input.contains(" ")) {
String result = input.replaceAll(" ", " +");
if (!result.trim().startsWith("+")) {
result = '+' + result;
}
return result;
} else {
return input;
}
}
int endIndex = startIndex + matchingCloseParenthesesIndex(input.substring(startIndex));
if (endIndex == -1) {
System.out.println("Invalid input!!!");
return "";
}
String first = "";
String last = "";
if (startIndex > 0) {
first = input.substring(0, startIndex);
}
if (endIndex < input.length() - 1) {
last = input.substring(endIndex + 1);
}
String result = formatSpaces(first);
String parenthesesStr = input.substring(startIndex + 1, endIndex);
if (last.startsWith(" ") && first.isEmpty()) {
result = result + "+";
}
result = result + "("
+ formatSpaces(parenthesesStr)
+ ")"
+ formatSpaces(last);
return result;
}
private static int matchingCloseParenthesesIndex(String input) {
int counter = 1;
char[] chars = input.toCharArray();
for (int i = 1; i < chars.length; i++) {
char ch = chars[i];
if (ch == '(') {
counter++;
} else if (ch == ')') {
counter--;
}
if (counter == 0) {
return i;
}
}
return -1;
}
}
公共类测试{
公共静态void main(字符串[]args){
字符串输入=“aa | bb hh cc | dd(a | b)”;
字符串结果=formatSpaces(formatPipes(输入)).replaceAll(“\\$”,”);
系统输出打印项次(结果);
}
专用静态字符串格式管道(字符串输入){
while(true){
char[]chars=input.toCharArray();
int pIndex=input.indexOf(“|”);
如果(pIndex==-1){
返回输入;
}
input=input.substring(0,pIndex)+“$”+input.substring(pIndex+1);
int first=pIndex-1;
int close括号计数=0;
而(第一个>=0){
如果(字符[第一个]==')'){
闭括号计数++;
}
如果(字符[第一个]=='('){
如果(闭括号计数>0){
闭括号计数--;
}
}
如果(字符[第一个]=''){
如果(闭括号计数==0){
打破
}
}
第一--;
}
字符串结果;
如果(第一个>0){
结果=输入。子字符串(0,第一个+1)+“(”;
}否则{
result=“(”;
}
int last=pIndex+1;
int open圆括号计数=0;
while(最后0){
开括号计数--;
}
}
如果(字符[最后]=''){
if(open圆括号计数==0){
打破
}
}
last++;
}
if(last>=input.length()-1){
结果=结果+输入。子字符串(第一个+1)+“”;
}否则{
结果=结果+输入.子字符串(第一个+1,最后一个)+““””+输入.子字符串(最后一个);
}
输入=结果;
}
}
专用静态字符串格式空间(字符串输入){
if(input.isEmpty()){
返回“”;
}
int startIndex=input.indexOf(“”);
如果(startIndex==-1){
if(input.contains(“”){
字符串结果=input.replaceAll(“,”+”);
如果(!result.trim().startsWith(“+”)){
结果=“+”+结果;
}
返回结果;
}否则{
返回输入;
}
}
int-endIndex=startIndex+matchingclose括号索引(input.substring(startIndex));
如果(endIndex=-1){
System.out.println(“无效输入!!!”;
返回“”;
}
字符串优先=”;
字符串last=“”;
如果(起始索引>0){
第一个=输入子字符串(0,startIndex);
}
if(endIndex@ParameterizedTest
@CsvSource({
"a b,+a +b",
"a (b c),+a +(+b +c)",
"a|b,(a b)",
"a|b|c,(a b c)",
"aa|bb|(cc|(ff gg)) hh,+(aa bb (cc (+ff +gg))) +hh",
"(aa(bb(cc|ee)|ff) gg),(+aa(bb(cc ee) ff) +gg)",
"(a b),(+a +b)",
"(a(c|d) b),(+a(c d) +b)",
"bb(cc|ee),bb(cc ee)",
"((a|b) (a b)|b (c|d)|e),(+(a b) +((+a +b) b) +((c d) e))"
})
void testTransformString(String input, String output) {
Assertions.assertEquals(output, transformString(input));
}
@ParameterizedTest
@CsvSource({
"a b,+a +b",
"a b c,+a +b +c",
"a|b,(a b)",
"(a b),(+a +b)",
"(a|b),(a b)",
"a|b|c,(a b c)",
"(aa|bb cc|dd),(+(aa bb) +(cc dd))",
"(aa|bb|ee cc|dd),(+(aa bb ee) +(cc dd))",
"aa|bb|cc|ff gg hh,+(aa bb cc ff) +gg +hh"
})
void testTransformBasic(String input, String output) {
Assertions.assertEquals(output, transformBasic(input));
}