2015-07-27 5 views
6

std :: regex का उपयोग करके और फ़ाइल पथ दिया गया है, मैं केवल .txt के साथ समाप्त होने वाले फ़ाइल नामों से मेल खाना चाहता हूं और यह _test.txt या .txtTEMP के रूप में नहीं हैं। कोई अन्य अंडरस्कोर ठीक है।रेगेक्स केवल कुछ फ़ाइल नामों से मेल खाने के लिए

तो, उदाहरण के लिए:

  • somepath/testFile.txt मेल खाना चाहिए।
  • somepath/test_File.txt मेल खाना चाहिए।
  • somepath/testFile_test.txt मेल नहीं खाना चाहिए।
  • somepath/testFile.txtTEMP मेल नहीं करना चाहिए।

ऐसे पैटर्न के लिए सही रेगेक्स क्या है?

मैं क्या कोशिश की है:

(.*?)(\.txt) ---> यह किसी भी फ़ाइल पथ .txt के साथ समाप्त होने से मेल खाता है।

फ़ाइलों को बाहर करने के कि _test शामिल मैं नकारात्मक lookahed का उपयोग करने की कोशिश की:

(.*?)(?!_test)(\.txt)

लेकिन यह काम नहीं किया।

मैंने नकारात्मक दिखने की भी कोशिश की लेकिन एमएसवीसी 14 (विजुअल स्टूडियो 2015) रेगेक्स बनाने के दौरान std::regex_error अपवाद फेंकता है, इसलिए मुझे यकीन नहीं है कि यह समर्थित नहीं है या मैं गलत वाक्यविन्यास का उपयोग कर रहा हूं।

उत्तर

2

क्या आप पोस्ट के आधार पर, ओपी संपादन के आधार पर इस पद्धति

^(?!.*_).*\.txt$ 

Demo


या इस पद्धति का उपयोग

^(.*(?<!_test)\.txt$) 

Demo

+0

धन्यवाद, यह काम करता है। – Banex

+0

क्या आप चुनिंदा रूप से केवल '* _test.txt' नामों को बहिष्कृत कर सकते हैं? – dlask

+0

@dlask "चुनिंदा" से आप अंत में 'TEMP' को अनदेखा कर रहे हैं? मुझे डर है कि ऐसा हो सकता है कि कोई '_test' नहीं बल्कि एक' TEMP' है। – Banex

2
^(?!.*?_test\.).*\.txt$ 

मुझे वीएस 2015 एटीएम तक पहुंच नहीं है, लेकिन यह केवल लुकहेड का उपयोग करता है, इसलिए काम करना चाहिए।

+0

बहुत कड़ाई से बोलते हुए: यह '_test.file.txt' की अनुमति नहीं देता है - जो कि चश्मा के अनुसार शायद अनुमति दी जानी चाहिए। हालांकि, व्यावहारिक मामले के लिए यह लगभग निश्चित रूप से सबसे अच्छा समाधान है। –

+0

मुझे लगता है कि मैं इसे संबोधित करने के लिए लुकहेड में 'txt' जोड़ सकता था। –

0

एक चाल जिसकी आप वास्तव में चाहते हैं उसे अनुकरण करने के लिए एक चाल है (लेकिन दुर्भाग्य से सी ++ 11 में समर्थित नहीं है), स्ट्रिंग को उलट करने के लिए है, फिर एक लुकहेड का उपयोग करें। आपका regexp तरह

^txt\.(?!tset_).* 

कुछ बन जाएगा अग्रदर्शी आप की कोशिश की के साथ समस्या यह है कि यह स्थिति जहां यह भी मिलान शुरू कर देना चाहिए पर लागू होता है है '.txt।' अंश। तो आपके regexp का हिस्सा '(?! _ Test) (। Txt)' कहता है, 'मुझे ऐसा कुछ चाहिए जो _test से शुरू नहीं होता है, लेकिन मिलान .txt' करता है। .txt में समाप्त होने वाली कुछ भी वास्तव में उस से मेल खाती है, यही कारण है कि यह काम नहीं करता है।

अद्यतन: नकारात्मक lookbehind साथ एक regex (कि C++ में काम नहीं करेगा, लेकिन उदाहरण के अजगर के लिए काम करता है):

^.*(?<!_test)\.txt$ 
+0

आपकी व्याख्या के लिए धन्यवाद। मैंने कोशिश की क्योंकि मैंने महसूस किया कि देखो, काम नहीं करेगा, जैसा आपने पुष्टि की थी। क्या आप कृपया अपने उत्तर में सही रेगेक्स का उपयोग करके शामिल कर सकते हैं? मैं जांच करूंगा कि यह वीएस2015 में काम करता है (शायद यह मेरा वाक्यविन्यास गलत था), और वैसे भी यह अन्य regex कार्यान्वयन के लिए उपयोगी हो सकता है। – Banex

+0

@ बेनेक्स: दुर्भाग्यवश, देखो के लिए कोई सही वाक्यविन्यास नहीं है - यह C++ 11 द्वारा आवश्यक रेगेक्स बोली में समर्थित नहीं है। यह प्रश्न भी देखें: http://stackoverflow.com/questions/14538687/using-regex-lookbehinds-in-c11 –

1

बेस्ट शर्त? Don't use regexes. विशेष रूप से एक सरल स्ट्रिंग खोज मामले में इस तरह।

  1. के बाद से इनपुट string के विस्तार होना चाहिए: ".txt" हम विस्तार करता है, तो जाँच करने के लिए की जरूरत नहीं है

    पहले वहाँ एक जोड़े को सरल अनुकूलन है कि प्रश्न के मानकों बनाया दिया जा सकता है कर रहे हैं ".txtTEMP"

  2. केवल स्थिति से मेल नहीं खाता है, जहां इनपुट string "_test.txt" में समाप्त होता है, यह जांचने की आवश्यकता है कि स्टेम "_test" में समाप्त होता है क्योंकि एक्सटेंशन पहले से ही ज्ञात है: "। txt "

दोनों इन चेकों को हमेशा string इनपुट के अंत से वर्णों की एक निश्चित संख्या ऑफसेट करने जा रहे हैं।

if(input.size() >= doMatchSize && 
    equal(input.end() - doMatchSize, input.end(), doMatch) && 
    (input.size() < doNotMatchSize || 
    !equal(input.end() - doNotMatchSize, input.end() - doMatchSize, doNotMatch))) 

आप एक जीवित उदाहरण देख सकते हैं:

constexpr auto doMatch = ".txt"; 
constexpr auto doMatchSize = strlen(doMatch); 
constexpr auto doNotMatch = "_test"; 
constexpr auto doNotMatchSize = strlen(doNotMatch) + doMatchSize; 

string input को देखते हुए इस प्रकार के रूप में यह सफलता के लिए परीक्षण किया जा सकता है: इन भाव में जाना जाता है यह संकलन समय पर सेटअप होना चाहिए है दोनों के लिए सभी जानकारी के बाद से यहां: http://ideone.com/7BcyFi

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

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