2009-03-12 11 views
43

मैं फ़ाइलों का एक समूह संभालने की कोशिश कर रहा हूं, और फिर फ़ाइल नामों में अपर्याप्त जानकारी को हटाने के लिए मुझे बदलने की जरूरत है; विशेष रूप से, मैं ब्रांड्स के अंदर पाठ को हटाने की कोशिश कर रहा हूं। उदाहरण के लिए:मैं रेगेक्स के साथ कोष्ठक के भीतर पाठ को कैसे हटा सकता हूं?

filename = "Example_file_(extra_descriptor).ext" 

और मैं फ़ाइलों को जहां निक्षिप्त अभिव्यक्ति बीच में या अंत में हो सकता है की एक पूरी गुच्छा regex के लिए, और चर लंबाई का चाहते हैं।

रेगेक्स कैसा दिखता है? पर्ल या पायथन वाक्यविन्यास को प्राथमिकता दी जाएगी।

+0

क्या आप सुनिश्चित हैं कि "extra_descriptor" में ")" शामिल नहीं हो सकता है? यदि यह समस्या बहुत कठिन हो सकती है ... – dmckee

+1

@dmckee: यदि माता-पिता * नेस्टेड * हो सकते हैं तो यह कठिन होता है, हालांकि यदि आप पहले '(' और अंतिम ') के बीच सबकुछ से छुटकारा पाना चाहते हैं तो यह है ज्यादा कठिन नहीं: बस '। *' के बजाय लालची '। *' का प्रयोग करें। –

+2

@j_random_hacker आप सही हैं, यह बहुत कठिन है क्योंकि नेस्टेड कोष्ठक को एफएसएम के साथ पहचाना नहीं जा सकता है (आपको घोंसले के स्तर का ट्रैक रखना है जो असीमित है) और इसलिए रेगेक्स द्वारा नहीं। इसके लिए आपको संभवतः घोंसले के सीमित स्तर तक सीमित होना है। – skyking

उत्तर

73
s/\([^)]*\)// 

तो अजगर में, तुम क्या चाहते हैं:

re.sub(r'\([^)]*\)', '', filename) 
+1

क्या पसंद करने का कोई कारण है। *? [^]] * – Kip

+1

@ जेएफ। सेबेस्टियन: तुम सही हो। –

+0

@Kip: नहीं। मुझे नहीं पता क्यों, लेकिन। * हमेशा पहली बात है जो दिमाग में आती है। –

2

आप sed उपयोग करने के लिए (संभवतः अपने कार्यक्रम के भीतर से निष्पादित खड़े हो सकते हैं, तो यह उतना ही आसान हो जाएगा के रूप में:

sed 's/(.*)//g' 
+0

आप अभिव्यक्ति को '। * 'अभिव्यक्त कर रहे हैं। – Gumbo

+0

@ गम्बो: नहीं, वह नहीं है। Sed में, "\\ (... \\)" समूह। – runrig

+0

ओपीएस, क्षमा करें। उसे नहीं पता था। – Gumbo

19

मैं का प्रयोग करेंगे:

\([^)]*\) 
3

अगर एक रास्ता हो सकती है कोष्ठकों तो r'\(.*?\)' regex पर्याप्त नहीं है:

import os, re 

def remove_parenthesized_chunks(path, safeext=True, safedir=True): 
    dirpath, basename = os.path.split(path) if safedir else ('', path) 
    name, ext = os.path.splitext(basename) if safeext else (basename, '') 
    name = re.sub(r'\(.*?\)', '', name) 
    return os.path.join(dirpath, name+ext) 

डिफ़ॉल्ट रूप से समारोह निर्देशिका और extention पथ के कुछ हिस्सों में parenthesized हिस्सा बरकरार रखता है।

उदाहरण:

>>> f = remove_parenthesized_chunks 
>>> f("Example_file_(extra_descriptor).ext") 
'Example_file_.ext' 
>>> path = r"c:\dir_(important)\example(extra).ext(untouchable)" 
>>> f(path) 
'c:\\dir_(important)\\example.ext(untouchable)' 
>>> f(path, safeext=False) 
'c:\\dir_(important)\\example.ext' 
>>> f(path, safedir=False) 
'c:\\dir_\\example.ext(untouchable)' 
>>> f(path, False, False) 
'c:\\dir_\\example.ext' 
>>> f(r"c:\(extra)\example(extra).ext", safedir=False) 
'c:\\\\example.ext' 
0
>>> import re 
>>> filename = "Example_file_(extra_descriptor).ext" 
>>> p = re.compile(r'\([^)]*\)') 
>>> re.sub(p, '', filename) 
'Example_file_.ext' 
5

आप पूरी तरह एक regex उपयोग करने की आवश्यकता नहीं है, तो उपयोग पर्ल के Text::Balanced का उपयोग कर कोष्ठक को दूर करने पर विचार करें।

use Text::Balanced qw(extract_bracketed); 

my ($extracted, $remainder, $prefix) = extract_bracketed($filename, '()', '[^(]*'); 

{ no warnings 'uninitialized'; 

    $filename = (defined $prefix or defined $remainder) 
       ? $prefix . $remainder 
       : $extracted; 
} 

आप सोच रहे होंगे, "यह सब क्यों करते हैं जब एक रेगेक्स एक पंक्ति में चाल करता है?"

$filename =~ s/\([^}]*\)//; 

टेक्स्ट :: संतुलित हैंडल नेस्टेड कोष्ठक हैंडल करता है। तो $filename = 'foo_(bar(baz)buz)).foo' ठीक से निकाला जाएगा। यहां पेश किए गए रेगेक्स आधारित समाधान इस स्ट्रिंग पर असफल हो जाएंगे। पहला बंद करने वाले माता-पिता पर रुक जाएगा, और दूसरा उन्हें खाएगा।

$ filename = ~ s/([^}] *) //; # रिटर्न 'foo_buz))। Foo'

$ filename = ~ s /(.*)//; # रिटर्न 'foo_.foo'

# पाठ संतुलित उदाहरण रिटर्न '। Foo _) foo'

तो regex व्यवहार की या तो स्वीकार्य है, एक regex का उपयोग - लेकिन सीमाओं के दस्तावेज और मान्यताओं बनाया जा रहा है ।

+0

जबकि मुझे पता है कि आप नेस्टेड कंस्ट्रैसिस (क्लासिक) रेगेक्स के साथ पार्स नहीं कर सकते हैं, अगर आपको पता है कि आपको कभी भी नेस्टेड कंस्ट्रैसिस का सामना नहीं करना पड़ेगा, तो आप समस्या को सरल बना सकते हैं जो रेगेक्स के साथ किया जा सकता है, और काफी आसानी से। जब हमें इसकी आवश्यकता नहीं होती है तो पार्सर टूल का उपयोग करना अधिक होता है। –

+0

@ क्रिस लुटज़ - मुझे पहले वाक्य में "उपयोग" के बजाय "विचार" करना चाहिए था। कई मामलों में एक रेगेक्स नौकरी करेगा, इसलिए मैंने व्यवहार को स्वीकार्य होने पर रेगेक्स का उपयोग करने के लिए कहा है। – daotoad

0

जावा कोड:

Pattern pattern1 = Pattern.compile("(\\_\\(.*?\\))"); 
System.out.println(fileName.replace(matcher1.group(1), "")); 
9

पैटर्न है कि (में की तरह (xyz 123)Text (abc(xyz 123)) के बीच है

\([^()]*\) 

विवरण में paretheses कोई अन्य ( और ) पात्रों में सबस्ट्रिंग मेल खाता है:

  • \( - एक पहले दौर ब्रैकेट (ध्यान दें कि POSIX BRE में, ( इस्तेमाल किया जाना चाहिए, नीचे sed उदाहरण देखें)
  • [^()]* - शून्य या अधिक वर्ण के अलावा अन्य उन में परिभाषित (*Kleene star quantifier के कारण) negated character class/POSIX bracket expression, कि है, किसी भी तुलना में ( और )
  • \) अन्य वर्ण - एक बंद दौर ब्रैकेट (कोई POSIX BRE में भागने की अनुमति)

निकाला जा रहा है कोड के टुकड़े:

  • जावास्क्रिप्ट: string.replace(/\([^()]*\)/g, '')
  • पीएचपी: preg_replace('~\([^()]*\)~', '', $string)
  • पर्ल: $s =~ s/\([^()]*\)//g
  • अजगर: re.sub(r'\([^()]*\)', '', s)
  • सी #: Regex.Replace(str, @"\([^()]*\)", string.Empty)
  • वीबी।नेट: Regex.Replace(str, "\([^()]*\)", "")
  • जावा: s.replaceAll("\\([^()]*\\)", "")
  • रूबी: s.gsub(/\([^()]*\)/, '')
  • आर: gsub("\\([^()]*\\)", "", x)
  • लुआ: string.gsub(s, "%([^()]*%)", "")
  • बैश/sed: sed 's/([^()]*)//g'
  • Tcl: regsub -all {\([^()]*\)} $s "" result
  • सी ++ std::regex: std::regex_replace(s, std::regex(R"(\([^()]*\))"), "")
  • ऑब्जेक्टिव-सी:
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\([^()]*\\)" options:NSRegularExpressionCaseInsensitive error:&error]; NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:@""];
0

जो लोग अजगर का उपयोग करने के लिए, यहाँ एक सरल दिनचर्या कि parenthesized सबस्ट्रिंग निकालता है है, नेस्टेड कोष्ठक वाले लोगों सहित। ठीक है, यह एक regex नहीं है, लेकिन यह काम करेगा!

def remove_nested_parens(input_str): 
    """Returns a copy of 'input_str' with any parenthesized text removed. Nested parentheses are handled.""" 
    result = '' 
    paren_level = 0 
    for ch in input_str: 
     if ch == '(': 
      paren_level += 1 
     elif (ch == ')') and paren_level: 
      paren_level -= 1 
     elif not paren_level: 
      result += ch 
    return result 

remove_nested_parens('example_(extra(qualifier)_text)_test(more_parens).ext') 
संबंधित मुद्दे