কীভাবে কেবল বন্দী দলগুলিকে প্রতিস্থাপন করা যায়?


194

স্ট্রিংয়ের আগে এবং পরে আমার এইচটিএমএল কোড রয়েছে:

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
ভবিষ্যতের পক্ষ থেকে শুভেচ্ছা! আপনার সমাধানটি সত্যই ঝরঝরে দেখাচ্ছে। আপনি দয়া করে আপনার উত্তর ব্যাখ্যা করতে পারেন?
Polyducks

21
প্রথম বন্ধনীটি "গোষ্ঠী" তৈরি করতে ব্যবহৃত হয়, যা পরে বেস -১ সূচক নির্ধারিত হয়, এর সাথে প্রতিস্থাপনে অ্যাক্সেসযোগ্য হয় $, সুতরাং প্রথম শব্দটি (\w+)একটি গ্রুপে থাকে এবং হয়ে যায় $1, মাঝের অংশটি (\d+)দ্বিতীয় গ্রুপ হয়, (তবে পায়) প্রতিস্থাপনে উপেক্ষা করা হবে) এবং তৃতীয় গ্রুপটি $3। সুতরাং আপনি যখন প্রতিস্থাপনের স্ট্রিংটি দেন "$1!new_ID!$3", তখন group 1 এবং $ 3 স্বয়ংক্রিয়ভাবে প্রথম গ্রুপ এবং তৃতীয় গোষ্ঠীর সাথে প্রতিস্থাপন করা হয়, যার ফলে 2 য় গ্রুপটিকে নতুন স্ট্রিংয়ের সাথে প্রতিস্থাপন করা যায়, তার চারপাশের পাঠ্য বজায় রাখা হয়।
মিশ্র

4
এটি বলা হচ্ছে, আমি কীভাবে এটি কাজ করে তা বুঝতে পেরে, আমি আরও মার্জিত সমাধানের আশা করছিলাম> <<তবে, আমি এখন আমার কোডটি নিয়ে এগিয়ে যেতে পারি!
মিশ্রিত 3

9
1) এমনকি আপনার capture d + 2 ক্যাপচার করার দরকার নেই কেন আপনি কেন বলেন যে এটি মার্জিত নয়? ক্যাপচারিং মানে জিনিস রাখা, এড়িয়ে দেওয়া নয়। আপনি যা রাখতে চান তা হ'ল আড়াআড়ি + d + তাই এটি পার্শ্ববর্তী অংশগুলি ক্যাপচার করার জন্য এটি সত্যই উপলব্ধি করে (এবং যথেষ্ট মার্জিত)।
সির

3
সুন্দর সমাধান। রূপান্তরটির ভিত্তি হিসাবে ক্যাপচার গ্রুপটি ব্যবহার করে আমরা ক্যাপচার গ্রুপগুলি প্রতিস্থাপন করতে চাইলে কী হবে? এটি করার জন্য কি সমানভাবে মার্জিত সমাধান রয়েছে? বর্তমানে আমি ক্যাপচার হওয়া গোষ্ঠীগুলিকে একটি তালিকায় সংরক্ষণ করেছি, সেগুলি লুপ করব এবং ক্যাপচার গ্রুপকে প্রতি পুনরাবৃত্তিতে রূপান্তরিত মান দিয়ে প্রতিস্থাপন করব
সুকি

15

এখন যেহেতু জাভাস্ক্রিপ্ট (হিসাবে lookbehind করেছে ES2018 ), নতুন পরিবেশে, আপনি গ্রুপ সম্পূর্ণরূপে এই মত পরিস্থিতিতে এড়াতে পারবেন। বরং, lookbehind কোন দল আপনি আটক বহু আগে থেকেই আসে, এবং জন্য lookahead পর আসে, এবং প্রতিস্থাপন জন্য মাত্র !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+")- characters এর পরে শব্দের অক্ষরের সন্ধান করুন " `

মনে রাখবেন যে লুকইহাইডটি বেশ নতুন। এটি ভি 8 এর আধুনিক সংস্করণগুলিতে (ক্রোম, অপেরা এবং নোড সহ) কাজ করে তবে বেশিরভাগ অন্যান্য পরিবেশে নয় , কমপক্ষে এখনও হয়নি। সুতরাং আপনি নোডে এবং আপনার নিজের ব্রাউজারে নির্ভরযোগ্যভাবে লুকবিহিন ব্যবহার করতে পারেন (এটি যদি ভি 8 এর একটি আধুনিক সংস্করণে চলে তবে) এটি এলোমেলো ক্লায়েন্টদের দ্বারা পর্যাপ্ত সমর্থনযোগ্য নয় (যেমন কোনও পাবলিক ওয়েবসাইটে)।


মাত্র একটি দ্রুত সময়ের পরীক্ষা চালিয়েছি,
কাইডো

তবে, উদাহরণস্বরূপ যদি আমি সংখ্যাটি বের করতে চাই, একাধিক এবং "এটি পিছনে রাখতে" চাই, আমাকেও গ্রুপ করতে হবে \d+, তাই না?
মোশ ফেউ

@ মোশফিউ একটি রিপ্লারার ফাংশন ব্যবহার করুন এবং পুরো ম্যাচ, অঙ্কগুলি ব্যবহার করুন: এর সাথে দ্বিতীয় প্যারামিটারটি প্রতিস্থাপন করুন match => match * 2। অঙ্কগুলি এখনও পুরো ম্যাচ, তাই গোষ্ঠীগুলির জন্য কোনও প্রয়োজন নেই
সারেন্টেন পারফরম্যান্স

বুঝেছি ধন্যবাদ!
মোশ ফেউ

2

ম্যাথিউর উত্তরের সামান্য উন্নতি শেষ ক্যাপচারিং গোষ্ঠীর পরিবর্তে চেহারা হতে পারে:

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

অথবা আপনি দশমিকের দিকে বিভক্ত হয়ে নতুন আইডির সাথে এতে যোগ দিতে পারেন:

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

উদাহরণ / বেঞ্চমার্ক এখানে: https://codepen.io/jogai/ful/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 এর ডানদিকে ডান প্যানেলে ব্যাখ্যা করা হয়েছে । আপনি যদি চান, আপনি এই লিঙ্কটিতেও দেখতে পারেন , কীভাবে এটি কিছু নমুনার ইনপুটগুলির সাথে মেলে।


রেজেক্স সার্কিট

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);

সম্পদ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.