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


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.