मैं अपना परिणाम प्राप्त करने का एक बेहतर तरीका खोजना चाहता हूं। मैं regex pattern फ़ॉर्म के सभी टेक्स्ट से मिलान करने के लिए (DD+ some text DDDD some other text) का उपयोग करता हूं, अगर और केवल अगर यह गैर-निश्चित चौड़ाई के पीछे की शर्तों से पहले नहीं है। मैं इन शर्तों को अपने REGEX pattern के अंदर कैसे शामिल कर सकता हूं?

aa = pd.DataFrame({"test": ["45 python 00222 sometext",
                            "python white 45 regex 00 222 somewhere",
                            "php noise 45 python 65000 sm",
                            "otherword 45 python 50000 sm"]})
pattern = re.compile("(((\d+)\s?([^\W\d_]+)\s?)?(\d{2}\s?\d{3})\s?(\w.+))")
aa["result"] = aa["test"].apply(lambda x: pattern.search(x)[0] if pattern.search(x) else None)
lookbehind = ['python', 'php']
aa.apply(lambda x: "" if any(look in x["test"].replace(x["result"], "") for look in lookbehind) else x["result"], axis=1)

आउटपुट वही है जिसकी मुझे उम्मीद थी

0    45 python 00222 sometext
1                            
2                            
3          45 python 50000 sm
1
J. Doe 9 अक्टूबर 2018, 18:35

2 जवाब

सबसे बढ़िया उत्तर

आप एक हैक का उपयोग कर सकते हैं जिसमें अपेक्षित मैच से पहले php या python को कैप्चर करना शामिल है, और यदि समूह खाली नहीं है (यदि यह मेल खाता है), तो वर्तमान मैच को छोड़ दें, अन्यथा, मैच मान्य है।

देखो

pattern = re.compile(r"(?:(php|python).*?)?((?:\d+\s?[^\W\d_]+\s?)?\d{2}\s?\d{3}\s?\w.+)")

पैटर्न में 2 कैप्चरिंग समूह होते हैं:

  • (?:(php|python).*?)? - अंतिम ? इस समूह को वैकल्पिक बनाता है, यह समूह 1 php या python से मेल खाता है और कैप्चर करता है, और फिर 0+ वर्ण, जितना संभव हो उतना कम
  • ((?:\d+\s?[^\W\d_]+\s?)?\d{2}\s?\d{3}\s?\w.+) - यह समूह 2 है जो मूल रूप से आपका पैटर्न है जिसमें कोई अतिरेक और समूह नहीं हैं।

यदि समूह 1 मेल खाता है, तो हमें एक खाली परिणाम लौटाना होगा, अन्यथा, समूह 2 मान:

def callback(v):
    m = pattern.search(v)
    if m and not m.group(1):
        return m.group(2)
    return ""

aa["test"].apply(lambda x: callback(x))

नतीजा:

0    45 python 00222 sometext
1                            
2                            
3          45 python 50000 sm
1
Wiktor Stribiżew 9 अक्टूबर 2018, 22:08

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

इसमें शामिल होना चाहिए:

  • गैर-अंकों का एक क्रम (संभवतः खाली)।
  • आपके "निषिद्ध" तारों में से कोई भी।

इस प्रकार, यदि जाँच की जाने वाली स्ट्रिंग में अजगर या php पहले है पहला अंक, यह लुकहेड विफल हो जाएगा, जिससे इस स्ट्रिंग को रोका जा सकेगा आगे की प्रक्रिया।

^ एंकर के कारण, शेष रेगेक्स को पहले अनुक्रम से मेल खाना चाहिए गैर-अंकों ("डीडी +" भाग से पहले क्या है) और फिर आपका होना चाहिए रेगेक्स।

तो उपयोग करने के लिए रेगेक्स इस प्रकार है:

^(?!\D*(?:python|php))\D*(\d+)\s?([^\W\d_]+)\s?(\d{2}\s?\d{3})\s?(\w+)

विवरण:

  • ^(?! - स्ट्रिंग की शुरुआत और इसके लिए नकारात्मक लुकहेड: <उल>
  • \D* - गैर-अंकों का एक क्रम (खाली हो सकता है)।
  • (?:python|php) - "निषिद्ध" स्ट्रिंग्स में से कोई भी, गैर-कैप्चरिंग के रूप में समूह (इसे कैप्चर करने की कोई आवश्यकता नहीं है)।
  • ) - नकारात्मक लुकहेड का अंत।
  • \D* - गैर-अंकों का एक क्रम (जिससे पहले आप मिलान करना चाहते हैं)।
  • (\d+)\s? - अंकों का पहला क्रम + वैकल्पिक स्थान।
  • ([^\W\d_]+)\s? - कुछ टेक्स्ट नंबर 1 + वैकल्पिक स्थान।
  • (\d{2}\s?\d{3})\s? - अंकों का दूसरा क्रम (वैकल्पिक के साथ बीच में जगह) + वैकल्पिक जगह।
  • (\w+) - कुछ टेक्स्ट नंबर 2।
  • दूसरे पर मेरे समाधान का लाभ यह है कि आप यह जांचने से मुक्त हैं कि पहला समूह मेल खाता है या नहीं। यहां आपको केवल "पॉजिटिव" केस मिलते हैं, जिन्हें किसी चेक की जरूरत नहीं होती है।

    काम करने वाले उदाहरण के लिए देखें https://regex101.com/r/gl9nWx/1

    1
    Valdi_Bo 9 अक्टूबर 2018, 22:54