ব্যবহারকারী ইনপুট স্ট্রিংকে নিয়মিত অভিব্যক্তিতে রূপান্তর করা হচ্ছে


333

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

আমার সমস্যাটি ব্যবহারকারী থেকে স্ট্রিং পাচ্ছে এবং এটিকে একটি নিয়মিত অভিব্যক্তিতে রূপান্তরিত করছে। যদি আমি বলি যে তাদের //প্রবেশ করানো রেগেক্সের চারপাশে তাদের দরকার নেই, তবে তারা পতাকা পছন্দ করতে পারে না, gএবং পছন্দ করে i। সুতরাং তাদের //মত প্রকাশের চারপাশে থাকতে হবে, তবে আমি কীভাবে সেই স্ট্রিংটিকে একটি রেজেক্সে রূপান্তর করতে পারি? এটি স্ট্রিংয়ের পরে এটি আক্ষরিক হতে পারে না এবং আমি এটি RegExp কনস্ট্রাক্টরের কাছে পাস করতে পারি না কারণ এটির স্ট্রিং এর স্ট্রিং না করে //। কোনও রেজিেক্সে কোনও ব্যবহারকারী ইনপুট স্ট্রিং তৈরি করার অন্য কোনও উপায় আছে কি? এরপরের সাথে স্ট্রিং এবং পতাকাগুলি পার্স করতে //হবে তারপরে এটি অন্যভাবে তৈরি করব? আমার কি তাদের একটি স্ট্রিং প্রবেশ করানো উচিত, এবং তারপরে পৃথকভাবে পতাকা প্রবেশ করানো উচিত?

উত্তর:


611

স্ট্রিং থেকে নিয়মিত এক্সপ্রেশন তৈরি করতে RegExp অবজেক্ট কনস্ট্রাক্টর ব্যবহার করুন :

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;

1
একটি ইনপুট ক্ষেত্র সহ অনলাইনের সরঞ্জামটি পেয়ে ভাল লাগবে
হোলস

61
এইভাবে এটি করার সময়, আপনাকে অবশ্যই ব্যাকস্ল্যাশ থেকে বাঁচতে হবে, যেমনvar re = new RegExp("\\w+");
জেডি স্মিথ

12
@ হোলস রিজেক্স ১০১০.কম হ'ল একটি দুর্দান্ত রেগেক্স অনলাইন সরঞ্জাম
হেরেরো

2
কোনও
ট্রেলিং

2
@ জেডিএসমিথ আমি আপনার উদাহরণে এটি বোঝাতে চাই নি। আমি বোঝাতে চাইছি যে আপনি যদি ডাবল উদ্ধৃতিগুলি রেগেক্সের অংশ হতে চান তবে যদি আপনার হার্ড কোডিং থাকে তবে আপনি তাদের পালাতে হবে escape স্পষ্টতই, এই স্ট্রিংটি কোনও <input>এইচটিএমএল ট্যাগের মতো চলকতে থাকে তবে এর কোনওটিই প্রয়োগ হয় না । var re = new RegExp("\"\\w+\"");RegExp কনস্ট্রাক্টর ব্যবহার করে হার্ড কোডড রেইগেক্সের একটি উদাহরণ এবং ডাবল উদ্ধৃতিগুলি রক্ষা করা প্রয়োজনীয় necessary ভেরিয়েবলের স্ট্রিং বলতে আমি কী বোঝাতে চাইছি তা হ'ল আপনি কেবলমাত্র করতে পারেন var re = new RegExp(str);এবং strসমস্যা ছাড়াই ডাবল কোটস বা ব্যাকস্ল্যাশ থাকতে পারে।
লুইস পাওলো

66
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

অথবা

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);

আপনার বিবেচনা করা উচিত যে একটি অবৈধ ইনপুট মতো /\/স্বীকৃত।
গম্বো

8
অথবা রেজিএক্সপ্যাক কনস্ট্রাক্টরকে জটিল পার্সার লেখার পরিবর্তে "নিয়মিত অভিব্যক্তিতে" পিছনে fail
বেনামে

21

এখানে একটি ওয়ান-লাইনার: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')

আমি এটি এস্কেপ-স্ট্রিং-রেজিএক্সপ্যাক এনপিএম মডিউল থেকে পেয়েছি ।

এটি চেষ্টা করে দেখুন:

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/

পতাকা সমর্থন সহ ট্যাগযুক্ত টেম্পলেট আক্ষরিক ব্যবহার:

function str2reg(flags = 'u') {
    return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
        , flags)
}

function evalTemplate(strings, ...values) {
    let i = 0
    return strings.reduce((str, string) => `${str}${string}${
        i < values.length ? values[i++] : ''}`, '')
}

console.log(str2reg()`example.com`)
// => /example\.com/u

15

জাভাস্ক্রিপ্ট RegExp অবজেক্ট কনস্ট্রাক্টর ব্যবহার করুন ।

var re = new RegExp("\\w+");
re.test("hello");

আপনি কনস্ট্রাক্টরের কাছে দ্বিতীয় স্ট্রিং আর্গুমেন্ট হিসাবে পতাকাগুলি পাস করতে পারেন। বিশদ জন্য ডকুমেন্টেশন দেখুন।


9

আমার ক্ষেত্রে ব্যবহারকারীর ইনপুট সামিটাইমগুলি সীমান্তকারীদের দ্বারা ঘেরাও করা হয়েছিল এবং কখনও কখনও তা নয়। তাই আমি আর একটি মামলা যুক্ত করেছি ..

var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
    // the parsed pattern had delimiters and modifiers. handle them. 
    var regexp = new RegExp(regParts[1], regParts[2]);
} else {
    // we got pattern string without delimiters
    var regexp = new RegExp(inputstring);
}

3
আপনি সবসময় .split()লম্বা রেজেক্স স্ট্রিংয়ের পরিবর্তে ফাংশনটি ব্যবহার করতে পারেন । এটি রিজেক্স স্ট্রিংটি এবং ডিলিমিটারগুলি তৈরি করবে (ধরে regParts = inputstring.split('/')নিবে regParts[1]রেজেক্সের regParts[2]সেটআপটি হ'ল /.../gim)। আপনি এখানে পরীক্ষা করে দেখতে পারেন যে এখানে ডিলিমিটার রয়েছে কিনা regParts[2].length < 0
জেকেরট00

3

আমি আপনাকে বিশেষ পতাকাগুলির জন্য পৃথক চেকবক্স বা একটি পাঠ্যক্ষেত্র যুক্ত করার পরামর্শ দিই। এইভাবে এটি স্পষ্ট যে ব্যবহারকারীর কোনও যুক্ত করার দরকার নেই //। প্রতিস্থাপনের ক্ষেত্রে দুটি পাঠ্যক্ষেত্র সরবরাহ করুন। এটি আপনার জীবনকে অনেক সহজ করে তুলবে।

কেন? কারণ অন্যথায় কিছু ব্যবহারকারীর সংযোজন হবে অন্যগুলি //না করে। এবং কিছু একটি সিনট্যাক্স ত্রুটি করবে। এরপরে, আপনি এরটি ছিনিয়ে নেওয়ার পরে //, আপনি একটি সিন্ট্যাক্টিক্যালি বৈধ রেইগেক্স দিয়ে শেষ করতে পারেন যা ব্যবহারকারীর ইচ্ছা মতো কিছুই নয়, যার ফলে অদ্ভুত আচরণের ব্যবহার হয় (ব্যবহারকারীর দৃষ্টিকোণ থেকে)।


2

যখন স্ট্রিংটি অবৈধ হয় বা এতে পতাকা ইত্যাদি থাকে না তখনও এটি কাজ করবে:

function regExpFromString(q) {
  let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
  if (flags === q) flags = '';
  let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
  try { return new RegExp(pattern, flags); } catch (e) { return null; }
}

console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
            


2

আপনি যদি সত্যিই একটি স্ট্রিংকে একটি রেজেক্সে রূপান্তর করতে চান তবে নীচের ফাংশনটি ব্যবহার করে দেখুন:

function String2Regex(s){return new RegExp(s.match(/\/(.+)\/.*/)[1], s.match(/\/.+\/(.*)/)[1]);}

আপনি এটি এর মতো ব্যবহার করতে পারেন:

"abc".match(String2Regex("/a/g"))
> ["a"]

রেফারেন্সের জন্য, এখানে ফর্ম্যাট করা এবং আরও আধুনিক সংস্করণ:

const String2Regex = str => {
  // Main regex
  const main = str.match(/\/(.+)\/.*/)[1]

  // Regex options
  const options = str.match(/\/.+\/(.*)/)[1]

  // Return compiled regex
  return new RegExp(main, options)
}

1

পূর্ববর্তী উত্তরের জন্য ধন্যবাদ, এই ব্লকগুলি কোনও RegEx এ কনফিগারযোগ্য স্ট্রিং প্রয়োগ করার জন্য একটি সাধারণ উদ্দেশ্যে সমাধান হিসাবে কাজ করে .. পাঠ্য ফিল্টার করার জন্য:

var permittedChars = '^a-z0-9 _,.?!@+<>';
permittedChars = '[' + permittedChars + ']';

var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);

log.debug ('strFilterRegEx: ' + strFilterRegEx);

strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!@+]/ig, '');

1

আপনি চেকবাক্স ব্যবহার করে পতাকা চাইতে পারেন তারপরে এমন কিছু করুন:

var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);

দেখে মনে হচ্ছে RegEx পেছনের পি হারিয়েছে .. স্ট্যাক আমাকে 1 টি অক্ষর সম্পাদনা করতে দিবে না
জেন বো বো

-3

আমি evalএই সমস্যাটি সমাধান করতে ব্যবহার করি ।

উদাহরণ স্বরূপ:

    function regex_exec() {

        // Important! Like @Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk. 
        var regex = $("#regex").val();

        // eval()
        var patt = eval(userInput);

        $("#result").val(patt.exec($("#textContent").val()));
    }

3
ইউজার ইনপুট ইনপুট একটি সুরক্ষিত সুরক্ষা ঝুঁকি
স্যামুয়েল

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