자바; 문자열 바꾸기 (정규 표현식 사용)?


129

학교 프로젝트의 일부로 다음 형식의 문자열을 바꿔야합니다.

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

다음과 같이 :

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

정규 표현식으로 할 수 있다고 생각하지만 아직 어떻게해야할지 모르겠습니다.

도와 줄 수 있나요?

추신 실제 할당은 다항식 처리 Java 응용 프로그램을 구현하는 것이며, 이것을 사용하여 모델에서 뷰로 polynomial.toString ()을 전달하고 있으며 html 태그를 사용하여 예쁘게 표시하고 싶습니다.


2
실례합니다. 좀 더 구체적으로 말씀해 주 시겠어요? 무슨 말인지 모르겠네요.
— Dan Burzo

5
오래된 농담. codinghorror.com/blog/archives/001016.html 에 설명이 있습니다.
— Michael Myers

1
오 :) 나는 실제로 그 기사를 얼마 전에 읽은 것 같습니다 ... 그래서 당신은 정규식이 내 경우에 갈 길이 아니라고 제안하는 것입니까?
— Dan Burzo

그래서 확장 된 형태로만 다항식을 허용합니까?
— Adam Jaskiewicz

답변:


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

아 ...하지만 "5 * x"를 "5x"로 축소하는 것을 놓쳤습니다
— James Curran

몇 가지 문제 : \ ^는 \\ ^이어야하고 $는 \ $이어야합니다.
— cdmckay

"유효하지 않은 이스케이프 시퀀스"오류가 계속 발생합니다. 뭔가 누락 되었습니까?
— Dan Burzo

두 번째 매개 변수에서 오류가 발생합니다. str.replaceAll ( "\\ ^ ([0-9] +)", "<sup> \ $ 1 </ sup>"); 이해가
— 안가요

2
미리 컴파일 된 패턴을 사용할 수 있습니까? 동일한 정규식으로 replaceAll을 여러 번 수행하는 경우 유용 할 수 있습니다.
— qed

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

8
이것은 컴파일 된 Regex를 사용하기 때문에 최상의 IMO이지만 Pattern 객체는 정적 객체 여야합니다.
— Marcel Valdez Orozco

재미있는 점은 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 : 정규식이 무엇을하는지 이해해야합니다! 정규식은 거의 아는 사람들의 손에 위험 합니다. (따라서 내가 게시 한 인용문.)
— Michael Myers

@Dan, 그대로 정규식은 각 * 앞뒤에 공백을 예상합니다. 이것은 정규식에서 해결할 수 있지만 연습으로 남겨 두겠습니다.
— Lieven Keersmaekers

@단. 주석을 작성한 후 정규식을 약간 변경했습니다. 원래이었다 : (: \ d 개 +?) * X \ (^ : \ D?) 새로운 기능은 다음과 같습니다 (: \ d 개 +?) * X \ (^ : \ d 개 +)
— 리벤 Keersmaekers

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

단일 정규식 / 대체에서 두 대체를 결합하는 것은 x^3 - 6 * x실패 와 같은보다 일반적인식이 기 때문에 잘못된 선택 입니다.


3

이것이 일반적인 수학 표현식이고 괄호 표현식이 허용되는 경우 정규 표현식으로이를 수행하는 것이 매우 어렵습니다 (아마도 불가능할 것입니다).

당신이 보여준 것이 유일한 대체품이라면 그렇게 어렵지 않습니다. 먼저 *'s를 제거한 다음 Can Berk Güder가 ^'s 를 처리하기 위해 보여준 것처럼 캡처를 사용 합니다.


예, 나중에 PS 노트에서 이것을 사용하여 다항식의 기본 문자열 표현을 더 인간이 읽을 수있는 것으로 구문 분석하고 있다고 설명했습니다. 감사!
— Dan Burzo

다항식은 모두 괄호식이없는 형식으로 확장 될 수 있습니다. 괄호 일치는 매우 재미 있기 때문에 확장 된 형태로만 제한해서는 안됩니다.
— Adam Jaskiewicz

3

다항식은 무엇입니까? 당신이 그것을 "처리"한다면, 나는 어떤 시점에서 생성되는 일종의 하위 표현의 트리를 구상하고 있으며, 원시를 다시 파싱하는 것보다 문자열을 생성하는 데 사용하는 것이 훨씬 더 간단 할 것이라고 생각할 것입니다. 정규식으로 표현.

그냥 다른 사고 방식을 던지고 있습니다. 앱에서 다른 일이 일어나고 있는지 잘 모르겠습니다.


당신이 무슨 말을하는지 이해합니다 ... 그건 정말 저에게 많은 고통을 덜어 줄 것입니다.하지만 저는 모든 것을 분리하려고 노력하고 있습니다. 다항식이 콘솔과 같은 다른 컨텍스트에서 사용할 수있는 독립형 클래스가되기를 원했지만 내 접근 방식이 잘못되었을 수 있습니다. 어떻게 생각해?
— Dan Burzo

무슨 말인지 알겠습니다. html 태그를 Polynomial.toString ()에 통합하면 확실히 MVC가 깨집니다. 그래도 그렇게하면 정말 일이 더 쉬워 질 것이기 때문에 여전히 그렇게 할 것이라고 생각합니다. 아마도 toHtmlString () 또는 뭔가 ...
— 아담 Jaskiewicz

아니면 View가 다항식을 형식화하기 위해 특별히 사용하는 별도의 클래스일까요? 그러면 Polynomial 클래스 자체는 서식에 대해 알 필요가 없습니다.
— Herms

나는 새로운 방법을 만들었다 : toHTML (); 생각해 보면 toString ()과 toHTML ()은 기본적으로 개념적으로 동일하지만 형식화에 대해 다른 규칙을 사용한다는 점만 다릅니다.
— Dan Burzo

예,보기 전용 형식이 마음에 들지 않습니다. 개체 에 정적 유틸리티 메서드에서 거대한 switch 문이 아닌 다형성을 사용하여 많은 논리를 처리 할 수 ​​있습니다. 그것에서 오른쪽으로 내려 오면, toString ()이 ... 또한 서식 뷰 특정입니다
— 아담 Jaskiewicz

1

이 시도:

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

java.util.regex를 가져와야합니다.


'가져 오기'팁에 감사드립니다. 불행히도 Eclipse는 두 번째 매개 변수에 대한 오류를 제공합니다. "Invalid escape sequence"
— Dan Burzo 2010 년

흠 ... GroovyConsole에서 테스트하지만 Java에서는 테스트하지 않습니다. 또한이 모든 것이 Java 상용구에 포함되어 있는지 확인해야합니다 (즉, 클래스를 만들고 기본 메서드에 던짐).
— cdmckay

대체 문자열은 "<sup> $ 1 </ sup>"이어야하며 백 슬래시가 없어야합니다. Groovy는 백 슬래시에 대해 다른 규칙을 가지고 있습니다. Java로 코드를 테스트해야합니다.
— Alan Moore

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

^ 3에서 3을 감싸는 것을 처리하기 위해 regex에서 캡처하는 방법을 살펴보고 싶을 것입니다.


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 표입니다. 귀하의 답변은 문자 그대로 '최선의 방법이 아닐 수 있습니다'라고 말하며 이미이 스레드에 더 나은 솔루션이 있음을 나타냅니다.
— Eric G

나는 그 위에 '더 나은'답을 볼 수 없다 ...하지만 어떤 경우에는 아래에 더 나은 답이있다.
— sergeych

0

antlr4를 살펴보십시오. 정규식 만 사용하는 것보다 트리 구조를 만드는 데 훨씬 더 많은 도움이됩니다.

https://github.com/antlr/grammars-v4/tree/master/calculator(calculator.g4 에는 필요한 문법이 포함되어 있음)

간단히 말해서, 표현식을 구문 분석하는 문법을 정의하고, antlr을 사용하여 자바 코드를 생성하고, 트리가 빌드 될 때 평가를 처리하는 콜백을 추가합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.