केवल कैद किए गए समूहों को कैसे बदलें?


194

मेरे पास स्ट्रिंग से पहले और बाद में HTML कोड है:

name="some_text_0_some_text"

मैं कुछ इस तरह से प्रतिस्थापित 0करना चाहूंगा:!NEW_ID!

इसलिए मैंने एक साधारण रेगेक्स बनाया:

.*name="\w+(\d+)\w+".*

लेकिन मैं यह नहीं देखता कि विशेष रूप से कैप्चर किए गए ब्लॉक को कैसे बदला जाए।

क्या किसी अन्य स्ट्रिंग द्वारा कैप्चर किए गए परिणाम ($ 1) को बदलने का कोई तरीका है?

परिणाम होगा:

name="some_text_!NEW_ID!_some_text"

जवाबों:


358

एक समाधान पूर्ववर्ती और निम्नलिखित पाठ के लिए कैप्चर जोड़ना है:

str.replace(/(.*name="\w+)(\d+)(\w+".*)/, "$1!NEW_ID!$3")

76
भविष्य की ओर से बधाई! आपका समाधान वास्तव में साफ-सुथरा दिखता है। क्या आप कृपया अपना उत्तर बता सकते हैं?
पोलड्यूक्स

21
कोष्ठक का उपयोग "समूह" बनाने के लिए किया जाता है, जिसे तब एक बेस -1 इंडेक्स सौंपा जाता है, जिसे एक के साथ प्रतिस्थापित किया जा सकता है $, इसलिए पहला शब्द (\w+)एक समूह में है, और बन जाता है $1, मध्य भाग (\d+)दूसरा समूह है, (लेकिन प्राप्त होता है) प्रतिस्थापन में नजरअंदाज), और तीसरा समूह है $3। इसलिए जब आप प्रतिस्थापित स्ट्रिंग देते हैं "$1!new_ID!$3", तो $ 1 और $ 3 को पहले समूह और तीसरे समूह के साथ स्वचालित रूप से बदल दिया जाता है, जिससे दूसरे समूह को नए स्ट्रिंग के साथ प्रतिस्थापित किया जा सकता है, इसके चारों ओर के पाठ को बनाए रखा जा सकता है।
मिश्रण ३ डी

4
यह कहा जा रहा है, जबकि मैं समझता हूं कि यह कैसे काम करता है, मैं और अधिक सुरुचिपूर्ण समाधान के लिए उम्मीद कर रहा था> <। फिर भी, मैं अब अपने कोड के साथ आगे बढ़ सकता हूं!
मिश्रण 3 डी

9
1) आपको \ d + 2 पर भी कब्जा करने की आवश्यकता नहीं है) आप यह क्यों कहते हैं कि यह सुरुचिपूर्ण नहीं है? पकड़ने का मतलब सामान रखना है, इसे फेंकना नहीं है। आप जो रखना चाहते हैं, वह AROUND \ d + है, इसलिए यह वास्तव में इन आसपास के हिस्सों पर कब्जा करने के लिए समझ में आता है (और बहुत सुंदर है)।
Sir4ur0n

3
अच्छा समाधान है। क्या होगा यदि हम कैप्चर समूह का उपयोग करके परिवर्तन के आधार के रूप में कैप्चर समूहों को बदलना चाहते हैं? क्या ऐसा करने के लिए एक समान रूप से सुरुचिपूर्ण समाधान है? वर्तमान में मैं एक सूची में कैप्चर किए गए समूहों को संग्रहीत करता हूं, उन्हें लूप करता हूं, और कैप्चर किए गए समूह को प्रत्येक पुनरावृत्ति पर परिवर्तित मूल्य से बदल देता हूं
sookie

15

अब जब कि जावास्क्रिप्ट (के रूप में lookbehind है ES2018 ), नए वातावरण पर, आप समूहों पूरी तरह से इस तरह की स्थितियों में बच सकते हैं। इसके बजाय, जिस समूह को आप कैप्चर कर रहे थे, उससे पहले जो दिख रहा है, उसके लिए खोजबीन करें, और उसके बाद मिलने वाला लुकहैड, और बस के साथ बदलें !NEW_ID!:

const str = 'name="some_text_0_some_text"';
console.log(
  str.replace(/(?<=name="\w+)\d+(?=\w+")/, '!NEW_ID!')
);

इस पद्धति के साथ, पूरा मैच केवल एक हिस्सा है जिसे प्रतिस्थापित करने की आवश्यकता है।

  • (?<=name="\w+)- name"शब्द वर्णों के लिए खोज की जाती है , (सौभाग्य से, लुकहाइंड को जावास्क्रिप्ट में निश्चित चौड़ाई नहीं होती है!)
  • \d+ - एक या अधिक अंकों का मिलान करें - पैटर्न का एकमात्र भाग एक नज़र में नहीं, स्ट्रिंग का एकमात्र हिस्सा जो परिणामी मैच में होगा
  • (?=\w+")- शब्द वर्णों के लिए लुकहेड उसके बाद " `

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


बस एक त्वरित समय परीक्षण चला, और यह काफी प्रभावशाली है कि इनपुट कैसे मायने रखता है: jsfiddle.net/60neyop5
काइदो

लेकिन अगर, उदाहरण के लिए, मैं संख्या निकालना चाहता हूं, तो कई और "इसे वापस डाल दें", मुझे समूह में भी होना होगा \d+, है ना?
मोश फेउ

@MoshFeu एक प्रतिकृति फ़ंक्शन का उपयोग करें और पूरे मैच का उपयोग करें, अंक: दूसरे पैरामीटर को इसके साथ बदलें match => match * 2। अंक अभी भी पूरे मैच हैं, इसलिए समूहों के लिए कोई आवश्यकता नहीं है
निश्चितरूपेण

पकड़ लिया। धन्यवाद!
मॉश फेउ

2

मैथ्यू के जवाब में थोड़ा सुधार अंतिम कैप्चरिंग समूह के बजाय एक लुकहेड हो सकता है:

.replace(/(\w+)(\d+)(?=\w+)/, "$1!NEW_ID!");

या आप दशमलव पर विभाजित कर सकते हैं और अपनी नई आईडी के साथ इस तरह से जुड़ सकते हैं:

.split(/\d+/).join("!NEW_ID!");

उदाहरण / बेंचमार्क यहाँ: https://codepen.io/jogai/full/oyNXBX


1

दो कब्जा समूहों के साथ भी संभव हो गया होता; मैंने अंकों के पहले और बाद में दो डैश को अतिरिक्त बाएँ और दाएँ सीमाओं के रूप में शामिल किया होगा, और संशोधित अभिव्यक्ति को देखा जाएगा:

(.*name=".+_)\d+(_[^"]+".*)

const regex = /(.*name=".+_)\d+(_[^"]+".*)/g;
const str = `some_data_before name="some_text_0_some_text" and then some_data after`;
const subst = `$1!NEW_ID!$2`;
const result = str.replace(regex, subst);
console.log(result);


यदि आप अभिव्यक्ति को एक्सप्लोर / सरल / संशोधित करना चाहते हैं, तो इसे regex101.com के शीर्ष दाएं पैनल पर समझाया गया है । यदि आप चाहें, तो आप इस लिंक में भी देख सकते हैं कि यह कुछ नमूना आदानों के साथ कैसे मेल खाता है।


RegEx सर्किट

jex.im नियमित अभिव्यक्ति की कल्पना करता है:

यहां छवि विवरण दर्ज करें


0

एक सरल विकल्प केवल अंकों को कैप्चर करना और उन्हें बदलना है।

const name = 'preceding_text_0_following_text';
const matcher = /(\d+)/;

// Replace with whatever you would like
const newName = name.replace(matcher, 'NEW_STUFF');
console.log("Full replace", newName);

// Perform work on the match and replace using a function
// In this case increment it using an arrow function
const incrementedName = name.replace(matcher, (match) => ++match);
console.log("Increment", incrementedName);

साधन

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