簡體   English   中英

用正則表達式拆分Java字符串

[英]Java String split with regex

我正在嘗試拆分表示為字符串的算術方程,並且我想保留多字符定界符: {==, !=, >=, <=, >, <}

這就是我所擁有的:

String expression = "2*(5 +1)- 3 * 2 >= 6^3.1 + 5";
expression = expression.replaceAll("\\s", "");
String[] parsedExpression = expression.split("((?<===)|(?===))|"
            + "((?<=>=)|(?=>=))|"
            + "((?<=!=)|(?=!=))|"
            + "((?<=<=)|(?=<=))|"
            + "((?<=>)|(?=>))|"
            + "((?<=<)|(?=<))");

但是,它像這樣拆分它:

[2*(5+1)-3*2, >, =, 6^3.1+5]

當所需的分割為:

[2*(5+1)-3*2, >=, 6^3.1+5]

我猜問題是,使用><作為定界符是導致問題的我的規則,但我不知道如何解決。

<>外觀周圍附加否定的超前(?!=) ,以確保當=是運算符的一部分時,它們不匹配:

String[] parsedExpression = expression.split("((?<===)|(?===)|"
        + "(?<=>=)|(?=>=)|"
        + "(?<=!=)|(?=!=)|"
        + "(?<=<=)|(?=<=)|"
        + "(?<=>(?!=))|(?=>(?!=))|"   // See here
        + "(?<=<(?!=))|(?=<(?!=)))"); // and here

IDEONE演示

System.out.println(Arrays.toString(parsedExpression)); 打印[2*(5+1)-3*2, >=, 6^3.1+5]

表達式中只能有一個標記(“>”,“> =,” ==“等)嗎? 您是否允許“ 5 <6 <7”之類的內容?

盡管它不使用正則表達式,但是您可以嘗試這樣的操作。

String[] parsedExpression = new String[3]; // assuming form "3 < 4". may need to modify a little
String[] tokens = {"==", "!=", "<", ">", "<=", ">="};

int idxOfToken = expression.indexOf(try every token until one is present);
String comparOp = ""; // set to operator you found
int additional = comparOp.length() == 2 ? 2 : 1;

parsedExpression[0] = expression.substring(0, idxOfToken);
parsedExpression[1] = comparOp;
parsedExpression[2] = expression.substring(idxOfToken + additional);

因為您正在分割環視寬度為零的環顧四周,所以即使您最初匹配兩個字符模式,匹配位置也不會移過整個模式。 相反,您可以匹配模式的其他部分。

因此,即使您最初匹配: >= ,其中的=也將再次匹配。

雖然可以使用環視拆分來解決您的問題,但它卻使正則表達式真正混亂,很難理解。 采取不同的方法會更好,更簡單。

例如,您可以匹配定界符或非定界符:

/[^><=]+|[><=]+/

與該模式匹配的所有列表將根據需要分割字符串。 這對您的輸入數據做出了某些假設,但如有必要,可以輕松進行調整。 例如,可以將其擴展為僅在有效的定界符上匹配。

看到它在這里工作。

更新1:第四個模式無法正常工作。

您只想在以下各項之前和之后拆分: ==!=>=<=>< ,所以(為了清楚起見,例如使用COMMENTS / (?x) )):

  • (?= [=!]= ) :在==之前, !=
  • (?= [><] )>之前, < (包括>=<=
  • (?<= [=!><]= )==!=>=<=
  • (?<= [><](?!=) ) :在>< ,不后面是=

可以使用|組合前兩個 (?= [=!]= | [><] )
可以使用|組合最后兩個 as (?<= [=!><]= | [><](?!=) )

因此,所有這些都意味着(?= [=!]= | [><] ) | (?<= [=!><]= | [><](?!=) ) (?= [=!]= | [><] ) | (?<= [=!><]= | [><](?!=) )使用COMMENTS標志,或僅:

(?=[=!]=|[><])|(?<=[=!><]=|[><](?!=))

測試

String regex = "(?=[=!]=|[><])|(?<=[=!><]=|[><](?!=))";
String[] split = "2*(5+1)-3*2 >= 6^3.1+5".split(regex);
System.out.println(Arrays.toString(split));

split = "a == b != c >= d <= e > f < g = h ! i".split(regex);
System.out.println(Arrays.toString(split));

產量

[2*(5+1)-3*2 , >=,  6^3.1+5]
[a , ==,  b , !=,  c , >=,  d , <=,  e , >,  f , <,  g = h ! i]

更新2

為了獲得完整的答案,我想展示一個基於Pushkindan1111想法的解決方案,該解決方案只是查找操作員。

該模式更加簡單易懂。 可能也會表現更好。

String text = "2*(5+1)-3*2 >= 6^3.1+5";
Matcher m = Pattern.compile("[=!]=|[><]=?").matcher(text);
if (m.find()) {
    String left  = text.substring(0, m.start());
    String oper  = m.group(); // or text.substring(m.start(), m.end());
    String right = text.substring(m.end());
    System.out.printf("[%s, %s, %s]%n", left, oper, right);
}

產量

[2*(5+1)-3*2 , >=,  6^3.1+5]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM