जावा; स्ट्रिंग बदलें (नियमित अभिव्यक्ति का उपयोग करके)?


129

स्कूल के लिए एक परियोजना के हिस्से के रूप में, मुझे फॉर्म से एक स्ट्रिंग बदलने की आवश्यकता है:

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

कुछ इस तरह से:

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

मेरा मानना ​​है कि यह नियमित अभिव्यक्तियों के साथ किया जा सकता है, लेकिन मुझे नहीं पता कि यह कैसे करना है।

क्या आप मुझे एक हाथ दे सकते हैं?

पुनश्च वास्तविक असाइनमेंट एक बहुपद प्रसंस्करण प्रसंस्करण जावा अनुप्रयोग को लागू करने के लिए है, और मैं इसका उपयोग मॉडल से दृश्य में polynomial.toString () पास करने के लिए कर रहा हूं, और मैं इसे html टैग का उपयोग करके एक सुंदर तरीके से प्रदर्शित करना चाहता हूं।


2
क्षमा करें, क्या आप अधिक विशिष्ट हो सकते हैं? मुझे समझ नहीं आ रहा है कि आपका क्या मतलब है।
डैन बर्ज़ो

5
पुराना चुटकुला। codinghorror.com/blog/archives/001016.html में एक स्पष्टीकरण है।
माइकल मायर्स

1
ओह :) मुझे लगता है कि मैं वास्तव में थोड़ी देर पहले उस लेख को पढ़ता हूं ... तो आप सुझाव दे रहे हैं कि मेरे मामले में regex रास्ता नहीं है?
डैन बर्ज़ो

तो आप केवल विस्तारित रूप में बहुपद की अनुमति दे रहे हैं?
एडम जस्कविज़

जवाबों:


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

आह ... लेकिन आप "5x" को "5x" तक गिराने से चूक गए
जेम्स कर्रन

युगल समस्याएं: \ ^ को \\ ^ और $ की जरूरत $ होना चाहिए।
cdmckay

अभी भी त्रुटि "अवैध एस्केप अनुक्रम" हो रही है ... क्या मुझे कुछ याद आ रहा है?
डैन बर्ज़ो

यह मुझे दूसरे पैरामीटर पर एक त्रुटि देता है: str.replaceAll ("\\ ^ ([0-9] +)", "<sup> \ $ 1 </ sup>"); मुझे यह नहीं मिला ... :(
डैन बर्ज़ो

2
क्या पहले से तैयार किए गए पैटर्न का उपयोग करना संभव है? यह उपयोगी हो सकता है यदि आप एक ही regex के साथ कई बार प्रतिस्थापन करते हैं।
QED

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

8
यह सबसे अच्छा IMO है, क्योंकि यह एक संकलित Regex का उपयोग करता है, लेकिन पैटर्न ऑब्जेक्ट एक स्थिर ऑब्जेक्ट होना चाहिए।
मार्सेल वाल्डेज़ ओरोज़्को

मजेदार बात यह है कि replaceAllविधि निहित है Pattern.compile(regex).matcher(testString).replaceAll(regexReplacementString)! इसलिए, यदि आप इस तरह से पैटर्न का फिर से उपयोग करते हैं, तो अनावश्यक वस्तुओं से बचा जाएगा। इसके अलावा, जैसा @MarcelValdezOrozco कहता है, इसे स्थिर बनाने से अनावश्यक पैटर्न संकलन को रोका जा सकेगा। :)
वरुण

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: सुनिश्चित करें कि आप समझते हैं कि regex क्या कर रहा है! Regexes उन लोगों के हाथों में खतरनाक है जो उन्हें लगभग जानते हैं। (इसलिए बोली मैं पोस्ट।)
माइकल मायर्स

@, जैसा कि यह खड़ा है, रेगेक्स प्रत्येक * के सामने और उसके बाद एक स्थान की उम्मीद करता है। यह रेगेक्स में हल किया जा सकता है लेकिन इसे एक एक्सर्साइज़ के रूप में छोड़ दें।
लेवेन केर्सेमेकर्स

@Dan। मैंने टिप्पणियों को बनाने के बाद रेगेक्स को थोड़ा बदल दिया। मूल था: (:? \ D +) * x \ ^ (:? \ D) नया है:: (:? \ _ + D) * * x \ ^ ((?? D +))
लेयंट केर्समेकर्स

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

कृपया ध्यान दें कि दोनों रिप्लेक्स को एक ही रेक्सक्स / रिप्लेसमेंट में शामिल करना एक बुरा विकल्प होगा क्योंकि अधिक सामान्य अभिव्यक्तियाँ जैसे x^3 - 6 * xकि विफल हो जाएंगी।


3

यदि यह किसी भी सामान्य गणित की अभिव्यक्ति के लिए है और अभिभावकीय अभिव्यक्तियों की अनुमति है, तो नियमित अभिव्यक्तियों के साथ ऐसा करना बहुत मुश्किल (शायद असंभव) होगा।

यदि केवल प्रतिस्थापन आपके द्वारा दिखाए गए हैं, तो ऐसा करना कठिन नहीं है। पहले स्ट्रिप आउट *, फिर कैप्चरिंग का उपयोग कर सकते हैं जैसे कि कैन बर्क गॉडर ने दिखाया है ^


हां, मैंने बाद में एक पीएस नोट में समझाया कि मैं इसका उपयोग बहुपद के मूल स्ट्रिंग प्रतिनिधित्व को कुछ और मानव पठनीय में पार्स करने के लिए कर रहा हूं। धन्यवाद!
डैन बर्ज़ो

बहुपद सभी को एक प्रकार से विस्तारित किया जा सकता है जिसमें कोई अभिभावकीय अभिव्यक्ति नहीं है। पर-मिलान बहुत मजेदार है, हालांकि, इसलिए आपको केवल विस्तारित रूप में खुद को सीमित नहीं करना चाहिए।
एडम जस्कविज़

3

आपका बहुपद क्या है? यदि आप इसे "प्रोसेस" कर रहे हैं, तो मैं कुछ बिंदुओं पर उत्पन्न होने वाले उप-अभिव्यक्तियों के किसी प्रकार के पेड़ की कल्पना कर रहा हूं, और यह सोचूंगा कि कच्चे का पुन: पार्स करने की तुलना में आपके स्ट्रिंग को उत्पन्न करने के लिए इसका उपयोग करना अधिक सरल होगा। एक रेक्स के साथ अभिव्यक्ति।

बस एक अलग तरीके की सोच को वहां फेंक दिया। मुझे यकीन नहीं है कि आपके ऐप में और क्या चल रहा है।


मैं समझता हूं कि आप जो कह रहे हैं ... वह वास्तव में मुझे बहुत पीड़ा देगा, लेकिन मैं चीजों को अलग रखने की कोशिश कर रहा हूं। मैं चाहता था कि बहुपत्नी एक स्टैंड-अलोन क्लास हो, जिसे अन्य संदर्भों में उपयोग किया जा सकता है, जैसे कि कंसोल ... लेकिन मेरा दृष्टिकोण गलत हो सकता है। तुम क्या सोचते हो?
डैन बर्ज़ो

मुझे पता है तुम्हारा क्या मतलब है। Polynomial.toString () में html टैग को शामिल करना निश्चित रूप से MVC को तोड़ रहा है। मुझे लगता है कि मैं अभी भी ऐसा कुछ करूंगा, हालांकि, क्योंकि यह वास्तव में चीजों को आसान बना देगा। शायद toHtmlString () या कुछ और ...
एडम जस्कविक्ज़

या शायद एक अलग वर्ग जिसे व्यू विशेष रूप से बहुपद स्वरूपण के लिए उपयोग करता है? तब बहुपद वर्ग को ही स्वरूपण के बारे में कुछ भी जानने की आवश्यकता नहीं है।
हर्म्स

मैंने एक नई विधि बनाई: HTML (); जब आप इसके बारे में सोचते हैं, तोस्ट्रिंग () और एचटीएमएल () मूल रूप से वैचारिक रूप से एक ही चीज होते हैं, सिवाय इसके कि वे प्रारूपण के लिए अलग-अलग नियमों को नियोजित करते हैं;
डैन बर्जो

हाँ, मैं वास्तव में की तरह है कि दृश्य-विशिष्ट स्वरूपण है नहीं है में वस्तु है, लेकिन यह आप बहुरूपता उपयोग करने के लिए एक तर्क के बजाय एक स्थिर उपयोगिता विधि में एक विशाल स्विच बयान बहुत कुछ के साथ सौदा करने की अनुमति होगी। जब यह इसके ठीक नीचे आता है, तोस्ट्रिंग () भी दृश्य-विशिष्ट स्वरूपण है ...
एडम जस्कविज़

1

इसे इस्तेमाल करे:

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

Java.util.regex आयात करना सुनिश्चित करें।


'आयात' टिप के लिए धन्यवाद। दुर्भाग्य से, ग्रहण मुझे दूसरे पैरामीटर के लिए एक त्रुटि प्रदान करता है: "अमान्य एस्केप अनुक्रम"
दान बर्ज़ो

हम्म् ... मैं इसे GroovyConsole में परीक्षण करता हूं लेकिन जावा पर नहीं। आपको यह भी सुनिश्चित करना होगा कि यह सब जावा बॉयलरप्लेट में है (यानी एक वर्ग बनाएं, और इसे एक मुख्य विधि में फेंक दें)।
cdmckay

प्रतिस्थापन स्ट्रिंग "<सुप> $ 1 </ sup>" होना चाहिए - कोई बैकस्लैश नहीं। ग्रूवी के बैकस्लैश के बारे में अलग-अलग नियम हैं; आपको जावा में अपने कोड का परीक्षण करना चाहिए।
एलन मूर

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 में रैपिंग को संभालने के लिए रेगेक्स में कैप्चरिंग में देखना चाहेंगे।


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 वोट हैं। आपका उत्तर शाब्दिक रूप से कहता है कि 'सबसे अच्छा तरीका नहीं हो सकता है' यह दर्शाता है कि बेहतर समाधान हैं, जो कि पहले से ही इस धागे में हैं।
एरिक जी

मैं इसके ऊपर कोई 'बेहतर' उत्तर नहीं देखता ... एक है कि कुछ मामलों में नीचे बेहतर है, हालांकि।
सेर्जिक

0

Antlr4 पर एक नज़र डालें। यह आपको नियमित रूप से अकेले अभिव्यक्ति की तुलना में एक पेड़ की संरचना बनाने में बहुत दूर मिलेगा।

https://github.com/antlr/grammars-v4/tree/master/calculator (कैलकुलेटर। g4 में आपका आवश्यक व्याकरण समाहित है)

संक्षेप में, आप व्याकरण को एक अभिव्यक्ति को पार्स करने के लिए परिभाषित करते हैं, जावा कोड उत्पन्न करने के लिए एंटीएल का उपयोग करते हैं, और जब पेड़ का निर्माण किया जा रहा है तो मूल्यांकन को संभालने के लिए कॉलबैक जोड़ते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.