2009-06-09 20 views
25

के लिए नियमित अभिव्यक्ति मुझे textbox इनपुट को सत्यापित करने की आवश्यकता है और केवल दशमलव इनपुट की अनुमति दे सकता है जैसे: X,XXX (दशमलव चिह्न से पहले केवल एक अंक और 3 की सटीकता)।दशमलव संख्या

मैं सी # का उपयोग कर रहा है और इस ^[0-9]+(\.[0-9]{1,2})?$ कोशिश?

+2

फ्रेमवर्क समाधान ('दशमलव.TryParse') के बजाय आप नियमित अभिव्यक्तियों का उपयोग क्यों करेंगे? –

उत्तर

48
^[0-9]([.,][0-9]{1,3})?$ 

यह अनुमति देता है:

0 
1 
1.2 
1.02 
1.003 
1.030 
1,2 
1,23 
1,234 

लेकिन इतने ही:

.1 
,1 
12.1 
12,1 
1. 
1, 
1.2345 
1,2345 
+5

\ 0-9] को बदलकर \ d 3 अक्षरों (6 कुल) में कटौती करता है और वही काम करता है। – UnkwnTech

+2

+1 लेकिन यह स्वीकार करना अच्छा नहीं होगा .1 क्योंकि यह 0.1 का वैध प्रतिनिधित्व है (दशमलव के साथ परीक्षण किया गया। पर्स)? – stevehipwell

+0

इसका सबसे सरल संस्करण "\ d (\। \ D {1,3}) होगा?" लेकिन "\ d (?: \। \ d {1,3}) का उपयोग कर?" इसका मतलब होगा कि एक समूह संग्रहित नहीं है। – stevehipwell

7
\d{1}(\.\d{1,3})? 

Match a single digit 0..9 «\d{1}» 
    Exactly 1 times «{1}» 
Match the regular expression below and capture its match into backreference number 1 «(\.\d{1,3})?» 
    Between zero and one times, as many times as possible, giving back as needed (greedy) «?» 
    Match the character “.” literally «\.» 
    Match a single digit 0..9 «\d{1,3}» 
     Between one and 3 times, as many times as possible, giving back as needed (greedy) «{1,3}» 


Created with RegexBuddy 

से मेल खाता है:
1,2
1,23
1 .234

+0

आप {1} – tanascius

+0

को भी छोड़ सकते हैं, मुझे एहसास हुआ कि, और परिवर्तन को प्रतिबिंबित करने के लिए संपादित किया गया है। – UnkwnTech

+0

आपके पास अभी भी \ d – stevehipwell

16

एक वैकल्पिक दृष्टिकोण है, जिसमें I18n समस्याएं नहीं हैं (',' या '।' लेकिन दोनों को अनुमति नहीं है): Decimal.TryParse

बस मूल्य अनदेखी परिवर्तित करने का प्रयास करें,।

bool IsDecimalFormat(string input) { 
    Decimal dummy; 
    return Decimal.TryParse(input, out dummy); 
} 

यह एक नियमित अभिव्यक्ति का उपयोग करने से काफी तेज है, नीचे देखें।

(Decimal.TryParse का अधिभार बेहतर नियंत्रण के लिए इस्तेमाल किया जा सकता है।)


प्रदर्शन परीक्षण के परिणाम: Decimal.TryParse: 0.10277ms, Regex: 0.49143ms

संहिता (PerformanceHelper.Run की तुलना में एक सहायक है पारित कर दिया पुनरावृत्ति संख्या के लिए प्रतिनिधि चलाता है और औसत TimeSpan रिटर्न):।

using System; 
using System.Text.RegularExpressions; 
using DotNetUtils.Diagnostics; 

class Program { 
    static private readonly string[] TestData = new string[] { 
     "10.0", 
     "10,0", 
     "0.1", 
     ".1", 
     "Snafu", 
     new string('x', 10000), 
     new string('2', 10000), 
     new string('0', 10000) 
    }; 

    static void Main(string[] args) { 
     Action parser =() => { 
      int n = TestData.Length; 
      int count = 0; 
      for (int i = 0; i < n; ++i) { 
       decimal dummy; 
       count += Decimal.TryParse(TestData[i], out dummy) ? 1 : 0; 
      } 
     }; 
     Regex decimalRegex = new Regex(@"^[0-9]([\.\,][0-9]{1,3})?$"); 
     Action regex =() => { 
      int n = TestData.Length; 
      int count = 0; 
      for (int i = 0; i < n; ++i) { 
       count += decimalRegex.IsMatch(TestData[i]) ? 1 : 0; 
      } 
     }; 

     var paserTotal = 0.0; 
     var regexTotal = 0.0; 
     var runCount = 10; 
     for (int run = 1; run <= runCount; ++run) { 
      var parserTime = PerformanceHelper.Run(10000, parser); 
      var regexTime = PerformanceHelper.Run(10000, regex); 

      Console.WriteLine("Run #{2}: Decimal.TryParse: {0}ms, Regex: {1}ms", 
           parserTime.TotalMilliseconds, 
           regexTime.TotalMilliseconds, 
           run); 
      paserTotal += parserTime.TotalMilliseconds; 
      regexTotal += regexTime.TotalMilliseconds; 
     } 

     Console.WriteLine("Overall averages: Decimal.TryParse: {0}ms, Regex: {1}ms", 
          paserTotal/runCount, 
          regexTotal/runCount); 
    } 
} 
+0

की बजाय \ d {1} है यह केवल तेज़ नहीं है, यह बहुत साफ है। –

1

मैं सिर्फपाया 0 में एक मुद्दा है कि यह हजारों सेपरेटर के लिए जिम्मेदार है। एन-यूएस में उदाहरण, 10,36.00 ठीक है। मैं एक विशिष्ट परिदृश्य में जहाँ हजारों विभाजक नहीं माना जाना चाहिए और इसलिए \d(\.\d) निकला सबसे अच्छा शर्त होने के लिए regex था। बेशक अलग-अलग इलाकों के लिए दशमलव चार चर रखना था।

+1

'Decimal.TryParse' के अधिभार का उपयोग करें जो 'न्यूमेर स्टाइल' पैरामीटर लेता है, और *' NumerStyles.AllowThousands' शामिल नहीं है। – Richard

0

जैसा कि मैंने इस साथ tussled, 3.5 में TryParse NumberStyles है: निम्नलिखित कोड भी हजारों विभाजक अनदेखी करने के लिए Regex बिना चाल करना चाहिए।

double.TryParse(length, NumberStyles.AllowDecimalPoint,CultureInfo.CurrentUICulture, out lengthD)) 

मूल प्रश्न के लिए प्रासंगिक नहीं है लेकिन यह पुष्टि करते हुए कि TryParse() वास्तव में एक अच्छा विकल्प है।

4

सामान्य, यानी असीमित दशमलव स्थानों में:

using System.Globalization; 

... 

NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo; 
Regex re = new Regex("^(?\\d+(" 
        + Regex.Escape(nfi.CurrencyDecimalSeparator) 
        + "\\d{1,2}))$"); 

:

^-?(([1-9]\d*)|0)(.0*[1-9](0*[1-9])*)?$

0

नेट में, मैं गतिशील रूप से वर्तमान सांस्कृतिक संदर्भ के दशमलव सेपरेटर के साथ नियमित अभिव्यक्ति का निर्माण करने की सलाह देते हैं आप 1000 सेपर विभाजक को दशमलव विभाजक के समान तरीके से अनुमति देकर regexp को पंप करना चाह सकते हैं।

संबंधित मुद्दे