Java - 如何获取字符串中特定字符的所有出现并将它们转移到非预定义位置?

Posted

技术标签:

【中文标题】Java - 如何获取字符串中特定字符的所有出现并将它们转移到非预定义位置?【英文标题】:Java - How can one take all occurrences of a specific character in a string and shift them to a non-predefined position? 【发布时间】:2016-08-19 07:19:42 【问题描述】:

我想将字符串中的“立方根”和“平方根”分别替换为“^(1/3)”和“^(1/2)”,但在操作数之后。

进行简单替换会将“^(1/3)”和“^(1/2)”放在数字之前,但我需要它们在数字之后(我正在使用来自 exp4j 的 ExpressionBuilder API ,这就需要这个)。

例如,给定这个字符串:

"cube root of 27 times cube root of 64 plus square root of 9 minus square root of 4"

我希望将其转换为:

"27^(1/3)*64^(1/3)+9^(1/2)-4^(1/2)"

这是我的尝试:

String equation = "cube root of 27 times square root of 45";
String r1 = equation.replaceAll("cube root of", "◊").replaceAll("square root of", "√")
        .replaceAll("times", "*").replaceAll("plus", "+").replaceAll("minus", "-")
        .replaceAll("divided by", "/").replaceAll(" ", "");

System.out.println(r1);
String r2 = null;
if (r1.contains("◊"))

    for (int i = r1.indexOf("◊")+1; i < r1.length(); i++)
    
        if(Character.isDigit(r1.charAt(i)))
        

        
        else
        
            System.out.println("i: " + i);
            r2 = r1.substring(r1.indexOf("◊")+1, i) + "^(1/3)" + r1.substring(i);
            break;
        
    

System.out.println(r2);

我已经用“立方根”替换了一个临时字符“◊”(写出整个短语很乏味),并且我已经让它为我工作,我得到的输出是:

◊27*√45
i: 3
27^(1/3)*√45

所以它只适用于一个“立方根”短语,而不是两个,并且无法使用“平方根”短语(它不在代码中,但我尝试在第一个 if( ) 块,我查看字符串是否包含“◊”符号。

我尝试在 if() 块中使用 OR r1.contains("√") 运算符,但它把我现有的代码搞砸了。我在网上到处寻找解决方案。我在我的程序中尝试了诸如 replaceCharAt(String s, int position, char c) 之类的方法来替换指定位置的字符,但我无法让它适用于所有出现的指定短语。

我花了数周时间寻找解决方案,但我找不到一个可以替换两个短语来进行数学运算的解决方案。

我将非常感谢在此处发布的任何帮助。

【问题讨论】:

对于初学者,不要使用replaceAll(),只需使用replace(),它仍然会替换所有出现的位置,但会进行纯文本替换(不是正则表达式替换) 那么,你想让“27的立方根”变成“27^(1/3)”等等? 是的,这是我的意图。如果这句话是“27 的立方根乘以 64 的立方根的 9 的 4 的平方根”,我希望它被翻译成:“27^(1/3)*64^(1/3 )*9^(1/2)*4^(1/2). * 运算符可以是任何东西,例如 +、- 甚至 / 【参考方案1】:

假设您要将“123 的立方根”转换为“123^(1/3)”等(您的问题不清楚),请捕获操作数并使用反向引用:

equation = equation.replaceAll("cube root of (\\S+)", "$1^(1/3)")
                   .replaceAll("square root of (\\S+)", "$1^(1/2)")
                   .replace("times", "*").replace("plus", "+").replace("minus", "-")
                   .replace("divided by", "/").replace(" ", "");

请注意,对于非正则表达式替换,纯文本 replace() 就足够了(并且是首选) - 它仍然替换所有出现的位置,但不使用正则表达式。


一些测试代码:

String equation = "cube root of 8 times square root of 4 plus cube root of 27 minus 3";
equation = equation.replaceAll("cube root of (\\S+)", "$1^(1/3)")
                   .replaceAll("square root of (\\S+)", "$1^(1/2)")
                   .replace("times", "*").replace("plus", "+").replace("minus", "-")
                   .replace("divided by", "/").replace(" ", "");
System.out.println(equation);

输出:

8^(1/3)*4^(1/2)+27^(1/3)-3

【讨论】:

这样一个简单而优雅的答案!非常感谢波西米亚人!我的意图是取一个字符串,例如:“27 的立方根减去 4 的平方根加上 9 的平方根乘以 64 的立方根”,并将其转换为:“27^(1/3) - 4^ (1/2) + 9^(1/2) * 64^(1/3),效果非常好? 再次感谢您! @cid np。学习正则表达式对您很有用。 fyi \S 表示“非空白字符”,使用方括号“捕获”输入,$1 表示“组 1”(捕获组从 1 开始编号)。【参考方案2】:

你好,这里是一个幼稚的实现。首先,您可以累积与您拥有的正则表达式字符串匹配的所有值。您有以下正则表达式。

类型为“cube”或“square”的正则表达式,后跟“root of”,后跟数字。现在您已经构建了您使用的正则表达式

    String mydata = "some string with 'the data i want' inside";
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find())

    System.out.println(matcher.group(0));

这将为您提取数字的值。一旦你这样做了,你需要用你想要的替换整个正则表达式。

可能有更好的实现。这是我脑海中的第一个。基本上,在尝试替换任何内容之前,您需要更多地使用正则表达式。并将其视为一个整体,一个完整的正则表达式,而不是试图将其划分为更小的元素。

【讨论】:

以上是关于Java - 如何获取字符串中特定字符的所有出现并将它们转移到非预定义位置?的主要内容,如果未能解决你的问题,请参考以下文章

Java语言中,怎么样查找一个特定的字符串,并返回它的索引位置

Linq Group by 并获取返回所有列的特定字符串规则的所有值

如何编写一个读取目录中所有文件名并在文件名中找到特定字符串的shell脚本?

如何删除所有出现的特定字符串一个字符串? [复制]

python如何获取txt文件一行中特定字符前或后的所有字符

如何避免以特定符号开头的行中字符串的文本突出显示[java]