200

As part of a project for school, I need to replace a string from the form:

5 * x^3 - 6 * x^1 + 1

to something like:

5x<sup>3</sup> - 6x<sup>1</sup> + 1

I believe this can be done with regular expressions, but I don't know how to do it yet.

Can you lend me a hand?

P.S. The actual assignment is to implement a Polynomial Processing Java application, and I'm using this to pass polynomial.toString() from the model to the view, and I want do display it using html tags in a pretty way.

1
  • Note that this is a school project, and most answers missed collapsing the "5 * x" to "5x". I.e., the question is actually not about string replacement, but the actual assignment is to implement a Polynomial Processing Java application. Commented Dec 15, 2022 at 15:24

11 Answers 11

247
str.replaceAll("\\^([0-9]+)", "<sup>$1</sup>");
Sign up to request clarification or add additional context in comments.

11 Comments

ah... but you missed collapsing the "5 * x" to "5x"
Couple problems: \^ needs to be \\^ and $ needs to be \$.
Still getting error "invalid escape sequence" ... am i missing something?
this gives me an error at the second parameter: str.replaceAll("\\^([0-9]+)", "<sup>\$1</sup>"); I don't get it... :(
Is it possible to use a precompiled pattern? This might be useful if you do replaceAll with the same regex many times.
|
60
private String removeScript(String content) {
    Pattern p = Pattern.compile("<script[^>]*>(.*?)</script>",
            Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
    return p.matcher(content).replaceAll("");
}

2 Comments

This is the best IMO, because it uses a compiled Regex, but the Pattern object should be a static object.
Fun thing is that the replaceAll method implicitly does Pattern.compile(regex).matcher(testString).replaceAll(regexReplacementString)! So, if you re-use the pattern this way, redundant objects will be avoided. Further, as @MarcelValdezOrozco says, making it static will prevent unnecessary pattern compile invocations. :)
23
String input = "hello I'm a java dev" +
"no job experience needed" +
"senior software engineer" +
"java job available for senior software engineer";

String fixedInput = input.replaceAll("(java|job|senior)", "<b>$1</b>");

Comments

13
"5 * x^3 - 6 * x^1 + 1".replaceAll("\\W*\\*\\W*","").replaceAll("\\^(\\d+)","<sup>$1</sup>");

please note that joining both replacements in a single regex/replacement would be a bad choice because more general expressions such as x^3 - 6 * x would fail.

Comments

10
import java.util.regex.PatternSyntaxException;

// (:?\d+) \* x\^(:?\d+)
// 
// Options: ^ and $ match at line breaks
// 
// Match the regular expression below and capture its match into backreference number 1 «(:?\d+)»
//    Match the character “:” literally «:?»
//       Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
//    Match a single digit 0..9 «\d+»
//       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
// Match the character “ ” literally « »
// Match the character “*” literally «\*»
// Match the characters “ x” literally « x»
// Match the character “^” literally «\^»
// Match the regular expression below and capture its match into backreference number 2 «(:?\d+)»
//    Match the character “:” literally «:?»
//       Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
//    Match a single digit 0..9 «\d+»
//       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
try {
    String resultString = subjectString.replaceAll("(?m)(:?\\d+) \\* x\\^(:?\\d+)", "$1x<sup>$2</sup>");
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
} catch (IllegalArgumentException ex) {
    // Syntax error in the replacement text (unescaped $ signs?)
} catch (IndexOutOfBoundsException ex) {
    // Non-existent backreference used the replacement text
}

3 Comments

@Dan: Be sure you understand what the regex is doing! Regexes are dangerous in the hands of people who almost know them. (Hence the quote I posted.)
@Dan, as it stands, the regex expects a space in front of and after each *. This can be solved in the regex but let's leave that as an excercise.
@Dan. I changed the regex a bit after creating the comments. Original was: (:?\d+) * x\^(:?\d) New is: (:?\d+) * x\^(:?\d+)
3

If this is for any general math expression and parenthetical expressions are allowed, it will be very difficult (perhaps impossible) to do this with regular expressions.

If the only replacements are the ones you showed, it's not that hard to do. First strip out *'s, then use capturing like Can Berk Güder showed to handle the ^'s.

2 Comments

Yes, I later explained in a P.S. note that I'm using this to parse a basic string representation of a polynomial into something more human readable. Thanks!
Polynomials can all be expanded to a form involving no parenthetical expressions. Paren-matching is great fun, though, so you shouldn't limit yourself to expanded form only.
3

What is your polynomial? If you're "processing" it, I'm envisioning some sort of tree of sub-expressions being generated at some point, and would think that it would be much simpler to use that to generate your string than to re-parse the raw expression with a regex.

Just throwing a different way of thinking out there. I'm not sure what else is going on in your app.

5 Comments

I understand what you're saying... that would indeed spare me a lot of suffering, but I'm trying to keep things separate. I wanted Polynomial to be a stand-alone Class that can be used in other context, such as the console... but my approach might be wrong. What do you think?
I see what you mean. Incorporating the html tags into Polynomial.toString() is definitely breaking MVC. I think I would still do something like that, though, because it really would make things easier. Perhaps toHtmlString() or something...
Or maybe a separate class that the View uses specifically for formatting the polynomial? Then the Polynomial class itself doesn't need to know anything about the formatting.
i made a new method: toHTML(); when you think about it, toString() and toHTML() are basically the same thing conceptually, except they employ different rules for formatting;
Yeah, I don't really like that the view-specific formatting is in the object, but it would allow you to use polymorphism to deal with a lot of the logic rather than a giant switch statement in a static utility method. When it comes right down to it, toString() is also view-specific formatting...
1

Try this:

String str = "5 * x^3 - 6 * x^1 + 1";
String replacedStr = str.replaceAll("\\^(\\d+)", "<sup>\$1</sup>");

Be sure to import java.util.regex.

3 Comments

Thanks for the 'import' tip. Unfortunately, Eclipse gives me an error for the second parameter: "Invalid escape sequence"
Hmmm... I test it in GroovyConsole but not Java. You also have to make sure that this is all in Java boilerplate (i.e. make a class, and throw it in a main method).
The replacement string should be "<sup>$1</sup>" - no backslashes. Groovy has different rules about backslashes; you should test your code in Java.
1
class Replacement 
{
    public static void main(String args[])
    {
        String Main = "5 * x^3 - 6 * x^1 + 1";
        String replaced = Main.replaceAll("(?m)(:?\\d+) \\* x\\^(:?\\d+)", "$1x<sup>$2</sup>");
        System.out.println(replaced);
    }
}

Comments

0

Try this, may not be the best way. but it works

String str = "5 * x^3 - 6 * x^1 + 1";
str = str.replaceAll("(?x)(\\d+)(\\s+?\\*?\\s+?)(\\w+?)(\\^+?)(\\d+?)", "$1$3<sup>$5</sup>");
System.out.println(str);

Comments

0

Take a look at antlr4. It will get you much farther along in creating a tree structure than regular expressions alone.

https://github.com/antlr/grammars-v4/tree/master/calculator (calculator.g4 contains the grammar you need)

In a nutshell, you define the grammar to parse an expression, use antlr to generate java code, and add callbacks to handle evaluation when the tree is being built.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.