2009-03-10 20 views
76

Come parte di un progetto per la scuola, ho bisogno di sostituire una stringa dal modulo:Java; Sostituire le stringhe (usando le espressioni regolari)?

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

a qualcosa di simile:

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

Credo che questo può essere fatto con le espressioni regolari, ma io non so ancora come farlo

Potete prestarmi una mano?

P.S. L'attuale compito è quello di implementare un'applicazione Polynomial Processing Java, e sto usando questo per passare polynomial.toString() dal modello alla vista, e voglio visualizzarlo usando i tag html in un modo carino.

+40

Ora hai due problemi.(Scusa, ma qualcuno ha dovuto dirlo.) –

+0

Scusami, puoi essere più specifico? Non capisco cosa intendi. – Dan

+1

Vecchio scherzo. http://www.codinghorror.com/blog/archives/001016.html ha una spiegazione. –

risposta

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

ah ... ma ti sei perso collassando il "5 * x" a "5x" –

+91

lasciandolo come esercizio al lettore =) –

+0

Problemi di coppia: \^deve essere \\^e $ deve essere $ . – cdmckay

0

Dovrai controllare l'acquisizione in espressioni regolari per gestire il wrapping del 3 in^3.

8
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: Assicurati di aver capito cosa le espressioni regolari sono dannose per le persone che * quasi * conoscono. (Da qui la citazione che ho postato). –

+0

@Dan, così com'è, la regex si aspetta uno spazio davanti e dopo ogni *. essere risolto nella regex ma lasciamo che sia un esercizio –

+0

@Dan. Ho cambiato un po 'regex dopo aver creato i commenti originale era: (:? \ d +) \ * x \^(:? \ d) Nuovo è: (:? \ d +) \ * x \^(:? \ d +) –

3

Se questo è per qualsiasi espressione matematica generale ed espressioni tra parentesi sono ammessi, sarà molto difficile (forse impossibile) per fare questo con le espressioni regolari.

Se le uniche sostituzioni sono quelle che hai mostrato, non è così difficile. Prima estrai la striscia *, quindi usa la cattura come Can Berk Güder ha mostrato di gestire lo ^.

+0

Sì, ho spiegato in seguito in un P.S. si noti che sto usando questo per analizzare una rappresentazione di stringa di base di un polinomio in qualcosa di più leggibile. Grazie! – Dan

+0

I polinomi possono essere tutti espansi in una forma che non implica espressioni parentetiche. L'abbinamento paren è molto divertente, quindi non dovresti limitarti solo alla forma espansa. –

0

Prova questo:

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

Assicurarsi di importare java.util.regex.

+0

Grazie per il suggerimento "importazione". Sfortunatamente, Eclipse mi dà un errore per il secondo parametro: "Sequenza di escape non valida" – Dan

+0

Hmmm ... Lo collaudo in GroovyConsole ma non in Java. Devi anche assicurarti che questo sia tutto in Java boilerplate (ad esempio, crea una classe e lanciala in un metodo principale). – cdmckay

+0

Sì, è ... strano. – Dan

3

Qual è il tuo polinomio? Se lo stai "processando", immagino che a un certo punto verrà generata una sorta di albero di sottoespressioni e penserei che sarebbe molto più semplice usarlo per generare la stringa piuttosto che analizzare nuovamente il raw espressione con una regex.

Basta lanciare un modo diverso di pensare là fuori. Non sono sicuro di cos'altro sta succedendo nella tua app.

+0

Capisco quello che stai dicendo ... che mi risparmierebbe un sacco di sofferenza, ma sto cercando di tenere le cose separate. Volevo che Polynomial fosse una classe autonoma che potesse essere utilizzata in altri contesti, come la console ... ma il mio approccio potrebbe essere sbagliato. Cosa ne pensi? – Dan

+0

Capisco cosa intendi. Incorporare i tag html in Polynomial.toString() sta sicuramente infrangendo MVC. Penso che farei comunque qualcosa del genere, perché renderebbe le cose più semplici. Forse toHtmlString() o qualcosa del genere ... –

+0

O forse una classe separata che la Vista utilizza specificamente per la formattazione del polinomio? Quindi la classe Polynomial non ha bisogno di sapere nulla sulla formattazione. – Herms

11
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>"); 
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); 
    } 
} 
19
private String removeScript(String content) { 
    Pattern p = Pattern.compile("<script[^>]*>(.*?)</script>", 
      Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
    return p.matcher(content).replaceAll(""); 
} 
+4

Questo è il migliore IMO, perché usa un Regex compilato, ma l'oggetto Pattern dovrebbe essere un oggetto statico. –

-2

Prova questo, potrebbe non essere il modo migliore. ma funziona

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

si prega di dare un motivo per cui un voto basso? – user5915163

+3

La domanda era del 2009 e ha già 8 risposte. La prima risposta ha 82 voti. La tua risposta dice letteralmente "potrebbe non essere il modo migliore" per indicare che ci sono soluzioni migliori, che ci sono già in questa discussione. –

+0

Non vedo una risposta "migliore" sopra di essa ... Ce n'è una che in alcuni casi è meglio sotto, però. – sergeych

0

Dai un'occhiata a antlr4. Ti porterà molto più avanti nella creazione di una struttura ad albero rispetto alle sole espressioni regolari.

https://github.com/antlr/grammars-v4/tree/master/calculator (calculator.g4 contiene la grammatica è necessario)

In poche parole, si definisce la grammatica per analizzare l'espressione, utilizzare ANTLR per generare codice Java, e aggiungere funzioni di callback per gestire la valutazione quando l'albero è di essere costruito.

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

si prega di notare che l'adesione sia le sostituzioni in un unico regex/sostituzione sarebbe una cattiva scelta, perché più espressioni generali come x^3 - 6 * x fallirebbe.

Problemi correlati