2010-02-03 10 views
5

मेरा पहला प्रश्न यहां पर!
बिंदु पर;
नियमित अभिव्यक्ति परिणामों से हेक्स कोड को हटाने का प्रयास

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

अब तक, मैं उपयोग कर रहा हूँ:

[#.]([a-zA-Z0-9_\-])* 

है जो काफी ठीक काम कर रहा है और #TB_window img#TB_Image और .TB_Image#TB_window के साथ ही #TB_window पाता है।

समस्या यह है कि यह सीएसएस फ़ाइल में हेक्स कोड टैग भी पाता है। यानी #FFF या #eaeaea
.png या .jpg या 0.75 भी पाए जाते हैं ..

वास्तव में यह बहुत तार्किक है कि वे पाए जाते हैं, लेकिन इसके लिए स्मार्ट वर्कअराउंड नहीं हैं?
ब्रैकेट {..} के बीच कुछ भी छोड़कर पसंद है?
(मुझे पूरा यकीन है कि यह संभव है, लेकिन मेरा regexp अनुभव अभी तक बहुत अधिक नहीं है)।

अग्रिम धन्यवाद!

चीयर्स!
माइक

उत्तर

2

सीएसएस एक बहुत ही सरल, नियमित भाषा है, जिसका अर्थ है कि इसे रेगेक्स द्वारा पूरी तरह से पार्स किया जा सकता है। इसके अलावा चयनकर्ताओं के समूह हैं, प्रत्येक के बाद कोलों द्वारा अलग विकल्पों के समूह के बाद।

ध्यान दें कि इस पोस्ट में सभी regexes वर्बोज़ और dotall निशानी नहीं लगाई होना चाहिए (/ s और/एक्स कुछ भाषाओं, re.DOTALL और अजगर में re.VERBOSE में)।

\s*  # Match any initial space 
([^{}]+?) # Ungreedily match a string of characters that are not curly braces. 
\s*  # Arbitrary spacing again. 
\{   # Opening brace. 
    \s*  # Arbitrary spacing again. 
    (.*?) # Ungreedily match anything any number of times. 
    \s*  # Arbitrary spacing again. 
\}   # Closing brace. 

यह एक विशेषता चयनकर्ता में एक उद्धृत धनुषाकार कोष्ठक होने के दुर्लभ मामले में काम नहीं करेगा (जैसे img[src~='{abc}']) या एक नियम में (जैसे background: url('images/ab{c}.jpg'):

(चयनकर्ताओं, नियम) की जोड़ी प्राप्त करने के लिए)। इसे रेगेक्स को जटिल बनाकर कुछ और तय किया जा सकता है:

\s*  # Match any initial space 
((?:  # Start the selectors capture group. 
    [^{}\"\']   # Any character other than braces or quotes. 
    |     # OR 
    \"     # An opening double quote. 
    (?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character. 
    \"     # And a closing double quote. 
    |     # OR 
    \'(?:[^\']|\\.)*\' # Same as above, but for single quotes. 
)+?)  # Ungreedily match all that once or more. 
\s*  # Arbitrary spacing again. 
\{   # Opening brace. 
    \s*  # Arbitrary spacing again. 
    ((?:[^{}\"\']|\"(?:[^\"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')*?) 
      # The above line is the same as the one in the selector capture group. 
    \s*  # Arbitrary spacing again. 
\}   # Closing brace. 
# This will even correctly identify escaped quotes. 

वाह, यह एक मुट्ठी भर है। लेकिन यदि आप इसे मॉड्यूलर फैशन में देखते हैं, तो आप देखेंगे कि यह उतना जटिल नहीं है जितना कि यह पहली नज़र में दिखता है।

अब, चयनकर्ताओं और नियमों को विभाजित करने के लिए, हमें उन पात्रों के तारों से मेल खाना पड़ेगा जो या तो गैर-डिलीमीटर (जहां एक डिलीमीटर चयनकर्ताओं के लिए अल्पविराम है और नियमों के लिए अर्धविराम है) या किसी भी चीज़ के साथ तारों को उद्धृत किया गया है। हम उसी पैटर्न का उपयोग करेंगे जो हमने ऊपर उपयोग किया था।

चयनकर्ताओं के लिए:

\s*  # Match any initial space 
((?:  # Start the selectors capture group. 
    [^,\"\']    # Any character other than commas or quotes. 
    |     # OR 
    \"     # An opening double quote. 
    (?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character. 
    \"     # And a closing double quote. 
    |     # OR 
    \'(?:[^\'\\]|\\.)*\' # Same as above, but for single quotes. 
)+?)  # Ungreedily match all that. 
\s*  # Arbitrary spacing. 
(?:,|$)  # Followed by a comma or the end of a string. 

नियमों के लिए:

\s*  # Match any initial space 
((?:  # Start the selectors capture group. 
    [^,\"\']    # Any character other than commas or quotes. 
    |     # OR 
    \"     # An opening double quote. 
    (?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character. 
    \"     # And a closing double quote. 
    |     # OR 
    \'(?:[^\'\\]|\\.)*\' # Same as above, but for single quotes. 
)+?)  # Ungreedily match all that. 
\s*  # Arbitrary spacing. 
(?:;|$)  # Followed by a semicolon or the end of a string. 

अंत में, प्रत्येक नियम के लिए, हम (! एक बार) एक बृहदान्त्र पर विभाजित एक संपत्ति-मान युग्म पाने के लिए कर सकते हैं।

लाना है कि सभी को एक साथ एक अजगर कार्यक्रम में (regexes ऊपर के रूप में ही हैं, लेकिन स्थान बचाने के लिए गैर शब्द):

import re 

CSS_FILENAME = 'C:/Users/Max/frame.css' 

RE_BLOCK = re.compile(r'\s*((?:[^{}"\'\\]|\"(?:[^"\\]|\\.)*"|\'(?:[^\'\\]|\\.)*\')+?)\s*\{\s*((?:[^{}"\'\\]|"(?:[^"\\]|\\.)*"|\'(?:[^\'\\]|\\.)*\')*?)\s*\}', re.DOTALL) 
RE_SELECTOR = re.compile(r'\s*((?:[^,"\'\\]|\"(?:[^"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')+?)\s*(?:,|$)', re.DOTALL) 
RE_RULE = re.compile(r'\s*((?:[^;"\'\\]|\"(?:[^"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')+?)\s*(?:;|$)', re.DOTALL) 

css = open(CSS_FILENAME).read() 

print [(RE_SELECTOR.findall(i), 
     [re.split('\s*:\s*', k, 1) 
     for k in RE_RULE.findall(j)]) 
     for i, j in RE_BLOCK.findall(css)] 

इस नमूने सीएसएस के लिए:

body, p#abc, #cde, a img .fgh, * { 
    font-size: normal; background-color: white !important; 

    -webkit-box-shadow: none 
} 

#test[src~='{a\'bc}'], .tester { 
    -webkit-transition: opacity 0.35s linear; 
    background: white !important url("abc\"cd'{e}.jpg"); 
    border-radius: 20px; 
    opacity: 0; 
    -webkit-box-shadow: rgba(0, 0, 0, 0.6) 0px 0px 18px; 
} 

span {display: block;} .nothing{} 

। .. हम (स्पष्टता के लिए स्थान दिया गया है) हो:

[(['body', 
    'p#abc', 
    '#cde', 
    'a img .fgh', 
    '*'], 
    [['font-size', 'normal'], 
    ['background-color', 'white !important'], 
    ['-webkit-box-shadow', 'none']]), 
(["#test[src~='{a\\'bc}']", 
    '.tester'], 
    [['-webkit-transition', 'opacity 0.35s linear'], 
    ['background', 'white !important url("abc\\"cd\'{e}.jpg")'], 
    ['border-radius', '20px'], 
    ['opacity', '0'], 
    ['-webkit-box-shadow', 'rgba(0, 0, 0, 0.6) 0px 0px 18px']]), 
(['span'], 
    [['display', 'block']]), 
(['.nothing'], 
    [])] 

पाठक के लिए सरल व्यायाम: सीएसएस कॉम दूर करने के लिए एक regex बारे में मेंट (/* ... */)।

0

सबसे पहले, मुझे नहीं पता कि आपके द्वारा पोस्ट किया गया आरई .TB_Image#TB_window कैसे मिलेगा। आप की तरह कुछ कर सकता है:

/^[#\.]([a-zA-Z0-9_\-]*)\s*{?\s*$/ 

इस टैग के बाद पंक्ति के आरंभ में # या . के किसी भी घटनाओं, मिलेगा, वैकल्पिक रूप से एक { और फिर एक नई पंक्ति के बाद।

ध्यान दें कि यह .TB_Image { something: 0; } (सभी एक पंक्ति पर) या div.mydivclass जैसी लाइनों के लिए काम नहीं करेगा क्योंकि . लाइन की शुरुआत में नहीं है।

संपादित: मुझे नहीं लगता कि नेस्ट ब्रेसिज़ सीएसएस में अनुमति दी जाती है, इसलिए यदि आप सभी डेटा में पढ़ सकते हैं और नई-पंक्तियों से छुटकारा पाने के लिए, आप की तरह कुछ कर सकता है:

/([a-zA-Z0-9_\-]*([#\.][a-zA-Z0-9_\-]+)+\s*,?\s*)+{.*}/ 

वहाँ एक रास्ता है न्यूलाइन को अनदेखा करने के लिए एक रेगेक्स को बताने के लिए, लेकिन मुझे यह अधिकार कभी नहीं लगता है।

+0

और यह '.foo, .bar' के लिए काम नहीं करता है। –

1

क्या इस बारे में:

([#.]\S+\s*,?)+(?=\{) 
0

यह वास्तव में नियमित अभिव्यक्ति के साथ हल करने के लिए के बाद से वहाँ संभावनाओं का एक बहुत हैं एक आसान काम नहीं है, पर विचार करें:

#someid ul img तरह
  • वंशज चयनकर्ताओं - होते हैं सभी मान्य टैग और रिक्त स्थान
  • टैग द्वारा अलग किए गए हैं जो . या # (यानी # से शुरू नहीं होते हैं)एचटीएमएल टैग नाम) - आप उन्हें मैच के लिए है क्योंकि वे गुण से कोई अन्य अंतर है
  • टिप्पणी
  • अधिक है कि मैं की अभी सोच भी नहीं सकते में उन लोगों की एक सूची प्रदान करने के लिए है

मुझे लगता है कि आपको अपनी पसंदीदा भाषा के लिए उपयुक्त कुछ सीएसएस पार्सिंग लाइब्रेरी पर विचार करना चाहिए।

+0

डाउनवोट करने का कोई कारण जोड़ने की आवश्यकता है? –

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