2009-03-10 5 views
76

В рамках проекта школы, мне нужно заменить строку из формы:Java; String заменить (используя регулярные выражения)?

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

к чему-то вроде:

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

Я считаю, это может быть сделано с регулярными выражениями, но я не знаю, как это сделать.

Можете ли вы оказать мне руку?

P.S. Фактическое назначение - реализовать приложение для обработки полиномиальной обработки Java, и я использую это, чтобы передать polyomial.toString() из модели в представление, и я хочу, чтобы она отображала его с помощью html-тегов довольно красиво.

+40

Теперь у вас есть две проблемы.(Извините, но кто-то должен был это сказать.) –

+0

Извините, вы можете уточнить? Я не понимаю, что вы имеете в виду. – Dan

+1

Старая шутка. http://www.codinghorror.com/blog/archives/001016.html есть объяснение. –

ответ

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

ах ... но вы пропустили рушится «5 * x» до «5x» –

+91

, мы оставляем это как упражнение читателю =) –

+0

Пара проблем: \^должно быть \\^и $ должно быть \ $ , – cdmckay

0

Вы хотите изучить захват в регулярном выражении, чтобы обработать обертывание 3 в^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: Убедитесь, что вы понимаете, что regex is do! Regexes опасны в руках людей, которые * почти знают их. (Отсюда цитата, которую я опубликовал.) –

+0

@Dan, поскольку это означает, регулярное выражение ожидает пробел перед и после каждого *. быть решен в регулярном выражении, но давайте оставим это как упражнение. –

+0

@Dan. Я немного изменил регулярное выражение после создания комментариев. Оригинал был: (:? \ d +) \ * x \^(:? \ d) Новое есть: (:? \ d +) \ * x \^(:? \ d +) –

3

Если это для любого общего математического выражения и вводные выражения допускаются, это будет очень трудно (даже невозможно), чтобы сделать это с регулярными выражениями.

Если только замены являются те, которые вы показали, что это не так трудно сделать. Сначала выровняйте *, затем используйте захват, как Can Berk Güder, чтобы обработать ^.

+0

Да, я позже объяснил в P.S. обратите внимание, что я использую это для синтаксического анализа базового строкового представления полинома во что-то более читаемое человеком. Спасибо! – Dan

+0

Полиномы могут быть расширены до формы, не содержащей выражений в скобках. Paren-matching - отличная игра, поэтому вы не должны ограничивать себя только расширенной формой. –

0

Попробуйте это:

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

Обязательно импортировать java.util.regex.

+0

Спасибо за отзыв «импорт». К сожалению, Eclipse дает мне ошибку для второго параметра: «Неверная escape-последовательность» – Dan

+0

Хммм ... Я тестирую его в GroovyConsole, но не Java. Вы также должны убедиться, что это все в шаблоне Java (т. Е. Создать класс и бросить его основным методом). – cdmckay

+0

Да, это ... странно. – Dan

3

Что вы полином? Если вы «обрабатываете» его, я представлю какое-то дерево подвыражений, сгенерированных в какой-то момент, и подумал бы, что было бы гораздо проще использовать это для генерации вашей строки, чем для повторного анализа сырой выражение с регулярным выражением.

Просто бросать другой способ мышления там. Я не уверен, что еще происходит в вашем приложении.

+0

Я понимаю, о чем вы говорите ... это действительно избавило бы меня от многих страданий, но я пытаюсь держать вещи раздельными. Я хотел бы, чтобы Polynomial был автономным классом, который можно использовать в другом контексте, таком как консоль ... но мой подход может быть неправильным. Как вы думаете? – Dan

+0

Я понимаю, что вы имеете в виду. Включение тегов html в Polynomial.toString() определенно нарушает MVC. Я думаю, что я все равно буду делать что-то подобное, потому что это действительно облегчит ситуацию. Возможно, toHtmlString() или что-то еще ... –

+0

Или, может быть, отдельный класс, который вид использует специально для форматирования полинома? Тогда самому полиномиальному классу не нужно ничего знать о форматировании. – 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

Это лучший IMO, потому что он использует скомпилированное Regex, но объект Pattern должен быть статическим объектом. –

-2

Попробуйте это, может быть не самым лучшим образом. но он работает

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

, пожалуйста, объясните причину, почему голосуете? – user5915163

+3

Вопрос был с 2009 года, и у него уже 8 ответов. В первом ответе 82 голоса. Ваш ответ буквально говорит «может быть не лучшим образом», указывая на то, что есть лучшие решения, которые есть, уже в этом потоке. –

+0

Я не вижу «лучшего» ответа над ним ... Есть один, который в некоторых случаях лучше внизу. – sergeych

0

Взгляните на antlr4. Это позволит вам значительно продвинуться в создании древовидной структуры, чем только регулярные выражения.

https://github.com/antlr/grammars-v4/tree/master/calculator (calculator.g4 содержит грамматику вам нужно)

В двух словах, можно определить грамматику для разбора выражения, использовать ANTLR для генерации кода Java, а также добавить обратные вызовы для обработки оценки, когда дерево является встроенный.

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

Обратите внимание, что присоединение обе замены в одном регулярное выражение/замена будет плохой выбор, потому что более общие выражения, такие как x^3 - 6 * x потерпит неудачу.

Смежные вопросы