जावास्क्रिप्ट regex - विकल्प के पीछे देखो?


143

यहाँ एक रेगेक्स है जो अधिकांश रेगेक्स कार्यान्वयन में ठीक काम करता है:

(?<!filename)\.js$

यह एक स्ट्रिंग के लिए .js से मेल खाता है जो फ़ाइल नाम के अलावा .js के साथ समाप्त होता है

जावास्क्रिप्ट में regex लुकअप नहीं है। क्या कोई भी वैकल्पिक रेगेक्स को एक साथ रख सकता है जो उसी परिणाम को प्राप्त करता है और जावास्क्रिप्ट में काम करता है?

यहाँ कुछ विचार हैं, लेकिन सहायक कार्यों की आवश्यकता है। मैं इसे केवल एक rexx के साथ प्राप्त करने की उम्मीद कर रहा था: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript


3
यदि आपको केवल एक विशिष्ट फ़ाइल नाम या फ़ाइल नाम की सूची की जांच करने की आवश्यकता है, तो सिर्फ दो चेक का उपयोग क्यों न करें? जाँच करें कि क्या यह .js में समाप्त होता है और फिर यदि ऐसा होता है, तो जांचें कि यह फ़ाइल नाम से मेल नहीं खाता है। js या इसके विपरीत।
si28719e

3
अपडेट: नवीनतम सार्वजनिक क्रोम संस्करण (v62) में बॉक्स के बाहर (संभवतः प्रायोगिक) लुकबाइंड शामिल हैं: डी नोट हालांकि लुक-आउट अभी भी प्रस्ताव चरण 3 में हैं: github.com/tc39/proposal-recxp-lookbehind । इसलिए, जब तक जावास्क्रिप्ट हर जगह इसका समर्थन करता है, तब तक इसमें कुछ समय लग सकता है। बेहतर उत्पादन में उपयोग करने के बारे में सावधान रहना!
एरिक बिर्कलैंड

2
# अद्यतन: ES2018 शामिल lookbehind दावे प्लस dotAll मोड (रों ध्वज) - - Lookbehind दावे - नाम कैप्चर समूहों - यूनिकोड संपत्ति पलायन:
एशले Coolman

2
बस का उपयोग (?<=thingy)thingyके लिए सकारात्मक lookbehind और (?<!thingy)thingyके लिए नकारात्मक lookbehindअब यह उनका समर्थन करता है।
Константин Ван

7
@ K._ फरवरी 2018 तक यह सच नहीं है !! और इसके लिए कुछ समय की आवश्यकता होगी क्योंकि ब्राउज़र और इंजन को विनिर्देश (ड्राफ्ट में वर्तमान) को लागू करना होगा।
आंद्रे फिग्यूएरेडो

जवाबों:


64

^(?!filename).+\.js मेरे लिये कार्य करता है

के खिलाफ परीक्षण किया गया:

  • टेस्ट.जेएस मैच
  • blabla.js मैच
  • filename.js कोई मेल नहीं

इस रेगेक्स के लिए एक उचित व्याख्या स्ट्रिंग से मेल खाने के लिए नियमित अभिव्यक्ति पर मिल सकती है ?

आगे देखें जावास्क्रिप्ट के संस्करण 1.5 के बाद से उपलब्ध है और सभी प्रमुख ब्राउज़रों द्वारा समर्थित है

Filename2.js और 2filename.js से मेल करने के लिए अपडेट किया गया, लेकिन filename.js नहीं

(^(?!filename\.js$).).+\.js


5
वह सवाल जो आपको थोड़ी अलग समस्या के बारे में बातचीत से जुड़ा हुआ है: एक स्ट्रिंग का मिलान करना जिसमें कहीं भी लक्ष्य शब्द नहीं है । यह बहुत सरल है: एक स्ट्रिंग से मेल खाना जो लक्ष्य शब्द से शुरू नहीं होता है।
एलन मूर

Thats वास्तव में अच्छा है, यह केवल ऐसे मामलों को याद करता है जैसे: filename2.js या filenameddk.js या समान। यह एक मैच है, लेकिन एक मैच होना चाहिए।
डेनियल

9
@daniel आपने लुक-बैक के लिए कहा, आगे से नहीं, आपने इस जवाब को क्यों स्वीकार किया?
hek2mgl

1
दिए गए एक से मेल नहीं खातेa.js
inetphantom

1
लुकबाइंड के साथ मूल रेगेक्स मेल नहीं खाता है 2filename.js, लेकिन यहां दिया गया रेगेक्स करता है। एक अधिक उपयुक्त एक होगा ^(?!.*filename\.js$).*\.js$। इसका मतलब है, किसी भी मैच *.js को छोड़ दें *filename.js
weibeld

153

संपादित करें: ECMAScript 2018 के बाद से, मुखरता से दिखावे (यहां तक ​​कि अनबाउंड) को मूल रूप से समर्थित किया जाता है

पिछले संस्करणों में, आप यह कर सकते हैं:

^(?:(?!filename\.js$).)*\.js$

यह स्पष्ट रूप से दिखता है कि लुकबाइंड अभिव्यक्ति स्पष्ट रूप से क्या कर रही है: स्ट्रिंग के प्रत्येक चरित्र की जांच करें यदि लुकबाइंड एक्सप्रेशन प्लस रेगेक्स के बाद मैच नहीं करेगा, और उसके बाद ही उस चरित्र को मिलान करने की अनुमति दें।

^                 # Start of string
(?:               # Try to match the following:
 (?!              # First assert that we can't match the following:
  filename\.js    # filename.js 
  $               # and end-of-string
 )                # End of negative lookahead
 .                # Match any character
)*                # Repeat as needed
\.js              # Match .js
$                 # End of string

एक और संपादन:

यह कहने के लिए मुझे दर्द होता है (विशेषकर जब से इस उत्तर को इतना बढ़ा दिया गया है) कि इस लक्ष्य को पूरा करने का एक आसान तरीका है। हर चरित्र पर नज़र की जाँच करने की कोई आवश्यकता नहीं है:

^(?!.*filename\.js$).*\.js$

साथ ही काम करता है:

^                 # Start of string
(?!               # Assert that we can't match the following:
 .*               # any string, 
  filename\.js    # followed by filename.js
  $               # and end-of-string
)                 # End of negative lookahead
.*                # Match any string
\.js              # Match .js
$                 # End of string

ऐसे बहुत सारे मामलों पर काम करता है, जहाँ पर पहले से मौजूद चरित्र हैं, उदाहरण के लिए: filename.js (वर्क्स-नॉमिनेट) filename2.js (कार्य-मिलान) blah.js (कार्य - मैच) 2filename .js (काम नहीं करता है - नामांकित) --- कहा जा रहा है कि, देखो की वही सीमा है जो मुझे अब तक महसूस नहीं हुई ...
daniel

9
@ डैनियल: ठीक है, आपका रेगेक्स (लुकअप के साथ) भी मेल नहीं खाता 2filename.js। मेरा रेगेक्स ठीक उसी तरह से मेल खाता है जैसे आपका उदाहरण रेगेक्स।
टिम पीत्जेकर

मेरी भोली को माफ कर दो, लेकिन क्या यहां गैर कब्जा करने वाले समूह के लिए उपयोग किया जाता है? मैंने हमेशा जाना है कि स्ट्रिंग में रिप्लेसमेंट के लिए रेफ़रेंस को वापस लाने के लिए केवल उपयोगी होने के लिए। जहाँ तक मुझे पता है, यह भी काम करेगा ^ (? फ़ाइल नाम \ .js $)। * \। Js $
मैं चाहता हूँ कि उत्तर

1
बिलकुल नहीं, वह रेगेक्स केवल "स्ट्रिंग" के आरंभ में "filename.js" की जाँच करता है। लेकिन ^(?!.*filename\.js$).*\.js$काम करेगा। उन स्थितियों के बारे में सोचने की कोशिश करना जहाँ ncgroup अभी भी आवश्यक हो सकता है ...
टिम पीटरज़

इस दृष्टिकोण को संक्षेप में प्रस्तुत किया जा सकता है: एक्स के पीछे देखने के बजाय, एक्स से पहले आने वाले हर चरित्र को देखें?
सरसापैरिला

25

मान लीजिए कि आप intपहले से नहीं सभी को ढूंढना चाहते हैं unsigned:

नकारात्मक रूप के लिए समर्थन के साथ पीछे:

(?<!unsigned )int

नकारात्मक दिखावे के समर्थन के बिना:

((?!unsigned ).{9}|^.{0,8})int

मूल रूप से विचार n पूर्ववर्ती वर्णों को पकड़ना है और नकारात्मक रूप से आगे के साथ मैच को बाहर करना है, लेकिन उन मामलों से भी मेल खाना है जहां कोई पूर्ववर्ती n वर्ण नहीं हैं। (जहां n लुक-बैक की लंबाई है)।

तो सवाल में regex:

(?<!filename)\.js$

इसका अनुवाद करेंगे:

((?!filename).{8}|^.{0,7})\.js$

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


मैं तो बस इस परिवर्तित: (?<!barna)(?<!ene)(?<!en)(?<!erne) (?:sin|vår)e?(?:$| (?!egen|egne))करने के लिए (?!barna).(?!erne).(?!ene).(?!en).. (?:sin|vår)e?(?:$| (?!egen|egne))जो मेरी जरूरतों के लिए काम कर देता है। बस इसे एक और "वास्तविक दुनिया" परिदृश्य के रूप में प्रदान करना। लिंक
Eirik Birkeland

मुझे लगता है कि आपका मतलब है:((?!unsigned ).{9}|^.{0,8})int
pansay

@pansay हां। धन्यवाद। मैंने सिर्फ अपनी प्रतिक्रिया को सही किया।
कामिल स्ज़ोट

2
अधिक सामान्यीकृत उत्तर के लिए धन्यवाद जो काम करता है जहां पाठ के भीतर गहराई से मिलान करने की आवश्यकता होती है (जहां प्रारंभिक ^ अव्यवहारिक होगा)!
मिलोस मर्दोविक

5

यदि आप आगे लेकिन पीछे देख सकते हैं, तो आप पहले स्ट्रिंग को उल्टा कर सकते हैं और फिर एक लुकहेड कर सकते हैं। कुछ और काम करने की आवश्यकता होगी, निश्चित रूप से।


8
यह उत्तर वास्तव में कुछ सुधार का उपयोग कर सकता है। यह मुझे एक टिप्पणी की तरह लगता है।
मिकमेकुसा

2

यह टिम पीटरज़कर के उत्तर के समतुल्य समाधान है (उसी उत्तर की टिप्पणियाँ भी देखें):

^(?!.*filename\.js$).*\.js$

इसका मतलब है, मैच *.jsको छोड़कर *filename.js

इस समाधान को प्राप्त करने के लिए, आप यह देख सकते हैं कि नकारात्मक लुकबाइंड को कौन से पैटर्न से बाहर रखा गया है, और फिर एक नकारात्मक लुकहैड के साथ इन पैटर्नों को बिल्कुल अलग करें।


-1

नीचे जावास्क्रिप्ट विकल्प दिखाया गया है जिसमें दिखाया गया है कि 'माइकल' वाले लोगों के अंतिम नाम को उनके पहले नाम के रूप में कैसे कैप्चर किया जाए।

1) इस पाठ को देखते हुए:

const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";

माइकल नाम के लोगों के अंतिम नामों की एक सरणी प्राप्त करें। परिणाम होना चाहिए:["Jordan","Johnson","Green","Wood"]

2) समाधान:

function getMichaelLastName2(text) {
  return text
    .match(/(?:Michael )([A-Z][a-z]+)/g)
    .map(person => person.slice(person.indexOf(' ')+1));
}

// or even
    .map(person => person.slice(8)); // since we know the length of "Michael "

3) समाधान की जाँच करें

console.log(JSON.stringify(    getMichaelLastName(exampleText)    ));
// ["Jordan","Johnson","Green","Wood"]

यहाँ डेमो: http://codepen.io/PiotrBerebecki/pen/GjwRoo

आप नीचे स्निपेट चलाकर भी इसे आज़मा सकते हैं।

const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";



function getMichaelLastName(text) {
  return text
    .match(/(?:Michael )([A-Z][a-z]+)/g)
    .map(person => person.slice(8));
}

console.log(JSON.stringify(    getMichaelLastName(inputText)    ));

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.