Java; 文字列置換(正規表現を使用)?


128

学校のプロジェクトの一環として、フォームの文字列を置き換える必要があります。

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

次のようなものに:

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

これは正規表現で実行できると思いますが、まだ方法がわかりません。

手を貸してくれませんか。

PS実際の割り当ては多項式処理Javaアプリケーションを実装することであり、これを使用してモデルからビューにpolynomial.toString()を渡します。HTMLタグを使用してきれいに表示したいと思います。


2
すみません、もっと具体的に教えてもらえますか?どういう意味かわかりません。
Dan Burzo 2009年

5
古い冗談。codinghorror.com/blog/archives/001016.htmlに説明があります。
マイケルマイヤーズ

1
ああ:)私は実際にしばらく前にその記事を読んだと思います...それで、あなたは私の場合、正規表現は行く方法ではないことを示唆していますか?
Dan Burzo 2009年

では、展開された形式の多項式のみを許可しますか?
アダムJaskiewicz 2009年

回答:


175
str.replaceAll("\\^([0-9]+)", "<sup>$1</sup>");

ああ...しかし、「5 * x」を「5x」に折りたたむのを忘れました
James Curran

カップルの問題:\ ^は\\ ^で、$は\ $である必要があります。
cdmckay 2009年

それでもエラー「無効なエスケープシーケンス」が発生します...何か不足していますか?
Dan Burzo 2009年

これにより、2番目のパラメーターでエラーが発生します。str.replaceAll( "\\ ^([0-9] +)"、 "<sup> \ $ 1 </ sup>");
わかり

2
プリコンパイルされたパターンを使用することは可能ですか?これは、replaceAllを同じ正規表現で何度も実行する場合に役立ちます。
2014年

38
private String removeScript(String content) {
    Pattern p = Pattern.compile("<script[^>]*>(.*?)</script>",
            Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
    return p.matcher(content).replaceAll("");
}

8
コンパイルされた正規表現を使用するため、これは最高のIMOですが、パターンオブジェクトは静的オブジェクトである必要があります。
マルセルバルデスオロスコ2016年

面白いのは、このreplaceAllメソッドが暗黙的に行うことPattern.compile(regex).matcher(testString).replaceAll(regexReplacementString)です。したがって、この方法でパターンを再利用すると、冗長なオブジェクトが回避されます。さらに、@ MarcelValdezOrozcoが言うように、静的にすることで、不要なパターンコンパイルの呼び出しを防ぐことができます。:)
varun

20
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>");

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
}

1
@ダン:正規表現が何をしているのかを必ず理解してください!正規表現は、それらをほとんど知っている人々の手に危険です。(したがって、私が投稿した引用です。)
マイケルマイヤーズ

@Dan、現状では、正規表現では各*の前後にスペースが必要です。これは正規表現で解決できますが、練習問題として残しておきましょう。
Lieven Keersmaekers 2009年

@ダン。コメントを作成した後、少し正規表現を変更しました。オリジナルは(:?\ d +)* x \ ^(:?\ d)New is:(:?\ d +)* x \ ^(:?\ d +)
Lieven Keersmaekers 2009年

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

などのより一般的な式x^3 - 6 * xは失敗するため、両方の置換を単一の正規表現/置換で結合することは悪い選択になることに注意してください。


3

これが一般的な数学式であり、括弧式が許可されている場合、正規表現でこれを行うことは非常に困難です(おそらく不可能です)。

唯一の代替品があなたが示したものである場合、それを行うのはそれほど難しくありません。最初にを*取り除き、次にを処理することを示したCan BerkGüderのようなキャプチャを使用します^


はい、後でPSのメモで説明しました。これを使用して、多項式の基本的な文字列表現をより人間が読める形式に解析しています。ありがとう!
Dan Burzo 2009年

多項式はすべて、括弧式を含まない形式に展開できます。ただし、括弧の照合はとても楽しいので、拡張形式だけに限定するべきではありません。
アダムJaskiewicz 2009年

3

あなたの多項式は何ですか?あなたがそれを「処理」している場合、私はある時点で生成されるある種のサブ式のツリーを想定しており、それを使用して文字列を生成するほうが、生正規表現による表現。

そこに別の考え方を投げかけるだけです。あなたのアプリで他に何が起こっているのか分かりません。


あなたの言っていることが理解できます...それは確かに私に多くの苦しみを与えることになるでしょうが、私は物事を分離しておくようにしています。多項式を、コンソールなどの他のコンテキストで使用できるスタンドアロンクラスにしたかったのですが...私のアプローチは間違っている可能性があります。どう思いますか?
Dan Burzo 2009年

どういう意味かわかります。HTMLタグをPolynomial.toString()に組み込むと、MVCが確実に機能しなくなります。それでも本当に簡単になるので、私はまだそのようなことをすると思います。おそらくtoHtmlString()または何か...
Adam Jaskiewicz 2009年

または、ビューが多項式をフォーマットするために特に使用する別のクラスですか?そうすれば、Polynomialクラス自体はフォーマットについて何も知る必要がなくなります。
Herms

新しいメソッドを作成しました:toHTML(); 考えてみると、toString()とtoHTML()は基本的には概念的に同じですが、フォーマットに異なる規則を採用しています。
Dan Burzo 2009年

ええ、ビュー固有のフォーマットが では、オブジェクトが、それはあなたが静的なユーティリティメソッドのロジックの多くではなく、巨大なswitch文に対処するための多型を使用することができるようになります。
つまり

1

これを試して:

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

必ずjava.util.regexをインポートしてください。


「インポート」のヒントをありがとう。残念ながら、Eclipseは2番目のパラメーターのエラーを返します:「無効なエスケープシーケンス」
Dan Burzo

うーん...私はGroovyConsoleでテストしますが、Javaではテストしません。また、これがすべてJavaボイラープレートであることを確認する必要があります(つまり、クラスを作成し、それをメインメソッドにスローします)。
cdmckay 2009年

置換文字列は "<sup> $ 1 </ sup>"である必要があります-バックスラッシュは使用できません。Groovyにはバックスラッシュに関する異なるルールがあります。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);
    }
}


0

これを試してください、最善の方法ではないかもしれません。でもうまくいく

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);

7
質問は2009年からで、すでに8つの回答があります。最初の回答は82票です。あなたの答えは文字通り「最善の方法ではないかもしれない」と述べており、すでにこのスレッドにはより良い解決策があることを示しています。
エリックG

その上に「より良い」答えはありません...しかし、いくつかのケースでは、以下の方が良いものがあります。
sergeych 16

0

antlr4を見てください。正規表現を単独で使用するよりも、ツリー構造の作成がはるかに簡単になります。

https://github.com/antlr/grammars-v4/tree/master/calculator(calculator.g4に は必要な文法が含まれています)

簡単に言えば、文法を定義して式を解析し、antlrを使用してJavaコードを生成し、コールバックを追加して、ツリーの構築時に評価を処理します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.