ভারসাম্য প্রথম বন্ধনীর সাথে মেলে নিয়মিত প্রকাশ


290

দুটি বাইরের বন্ধনীগুলির মধ্যে সমস্ত পাঠ্য নির্বাচন করতে আমার একটি নিয়মিত প্রকাশ দরকার need

উদাহরণ: some text(text here(possible text)text(possible text(more text)))end text

ফলাফল: (text here(possible text)text(possible text(more text)))


3
এই প্রশ্নটি খুব দরিদ্র কারণ এটি কী জিজ্ঞাসা করছে তা পরিষ্কার নয়। উত্তরগুলির সমস্ত এটি আলাদাভাবে ব্যাখ্যা করে। @ ডেভএফ আপনি কি দয়া করে প্রশ্নটি পরিষ্কার করতে পারেন?
ম্যাট ফেনউইক

1
: এই পোস্টে উত্তর stackoverflow.com/questions/6331065/...
sship21

উত্তর:


144

নিয়মিত ভাব প্রকাশের কাজটির ভুল সরঞ্জাম কারণ আপনি নেস্টেড স্ট্রাকচারগুলি, অর্থাৎ পুনরাবৃত্তি নিয়ে কাজ করছেন।

কিন্তু এই কাজ করতে একটি সহজ অ্যালগরিদম, যা আমি বর্ণনা হল এই উত্তরে একটি থেকে পূর্ববর্তী প্রশ্ন


15
.NET এর বাস্তবায়নে [ব্যালেন্সিং গ্রুপের সংজ্ঞাগুলি এমএসডিএন.ইমক্রোসফটকম /en-us/library/… রয়েছে যা এই ধরণের জিনিসটিকে মঞ্জুরি দেয়।
কার্ল জি

22
আমি একমত নই যে কয়েকটি কারণে নিয়মিত ভাব প্রকাশের জন্য এটি ভুল হাতিয়ার। 1) বেশিরভাগ নিয়মিত এক্সপ্রেশন বাস্তবায়নের ক্ষেত্রে এটির জন্য নিখুঁত সমাধান না হলে কার্যক্ষম। ২) প্রায়শই আপনি নিয়মিত অভিব্যক্তির সাথে উপযুক্ত অন্যান্য মানদণ্ডগুলিও কার্যকর হয় এমন একটি প্রসঙ্গে সীমাবদ্ধ প্রেরকগুলির জুড়ি খুঁজতে চেষ্টা করছেন। 3) প্রায়শই আপনি কিছু এপিআইতে একটি নিয়মিত ভাব প্রকাশ করে যা কেবল নিয়মিত এক্সপ্রেশন গ্রহণ করে এবং আপনার কোনও বিকল্প নেই।
কেনেথ বাল্ট্রিনিক


20
Regex হ'ল কাজের জন্য সঠিক সরঞ্জাম। এই উত্তরটি সঠিক নয়। Rogal111 এর উত্তর দেখুন।
অ্যান্ড্রু

4
সম্পূর্ণ উত্তর সহ একমত। যদিও রিজেক্সেপটিতে পুনরাবৃত্তির কিছু বাস্তবায়ন রয়েছে, তারা সীমাবদ্ধ-রাষ্ট্র মেশিনগুলির সমান এবং নেস্টেড কাঠামোগুলি নিয়ে কাজ করার জন্য অনুমান করা হয় না, তবে প্রসঙ্গ নিখরচায় ব্যাকরণগুলি এটি করে। ফর্মাল ব্যাকরণে হোমস্কির শ্রেণিবিন্যাস দেখুন।
নিক রোজ

138

আমি এই উত্তরটি দ্রুততার জন্য যুক্ত করতে চাই। আপডেট করতে নির্দ্বিধায়।


ব্যালেন্সিং গ্রুপগুলি ব্যবহার করে .NET রেজেক্স

\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)

যেখানে cগভীরতার কাউন্টার হিসাবে ব্যবহৃত হয়।

Regexstorm.com এ ডেমো


পিসিআরই একটি পুনরাবৃত্ত প্যাটার্ন ব্যবহার করে

\((?:[^)(]+|(?R))*+\)

Regex101 এ ডেমো ; বা কোনও বিকল্প ছাড়াই:

\((?:[^)(]*(?R)?)*+\)

Regex101 এ ডেমো ; বা সম্পাদনার জন্য নিবন্ধভুক্ত :

\([^)(]*+(?:(?R)[^)(]*)*+\)

Regex101 এ ডেমো ; প্যাটার্নটি এতে পেশ করা হয় (?R)যা উপস্থাপন করে (?0)

পার্ল, পিএইচপি, নোটপ্যাড ++, আর : পার্ল = সত্য , পাইথন : রেজেক্স প্যাকেজ সঙ্গে (?V1)পার্ল আচরণের জন্য।


রুবি ব্যবহার করেসুবি এক্সপ্রেসন কল

রুবি ২.০ সহ \g<0>সম্পূর্ণ প্যাটার্ন কল করতে ব্যবহার করা যেতে পারে।

\((?>[^)(]+|\g<0>)*\)

রুবুলারে ডেমো ; রুবি ১.৯ কেবলমাত্র গ্রুপ পুনরুক্তি ক্যাপচার সমর্থন করে :

(\((?>[^)(]+|\g<1>)*\))

রুবুলারে ডেমো  ( পারমাণবিক গ্রুপিং) রুবি ১.৯.৩ থেকে )


জাভাস্ক্রিপ্ট  API: XRegExp.matchRecursive

XRegExp.matchRecursive(str, '\\(', '\\)', 'g');

জেএস, জাভা এবং অন্যান্য রেজেক্স স্বাদগুলি নীড়ের 2 স্তর পর্যন্ত পুনরাবৃত্তি ছাড়াই:

\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)

Regex101 এ ডেমো । নিখরচায় আরও গভীর বাসা বাঁধতে হবে
ভারসাম্যহীন প্রথম বন্ধনে দ্রুত ব্যর্থ হওয়ার জন্য +কোয়ান্টিফায়ারটি ড্রপ করুন ।


জাভা : ফরোয়ার্ড রেফারেন্সগুলি @ জেটিয়া ব্যবহার করে একটি আকর্ষণীয় ধারণা


তথ্যসূত্র - এই রেজেক্সের অর্থ কী?


1
আপনি যখন কোনও গ্রাহককে একটি প্রাপ্য কোয়ান্টিফায়ার দিয়ে পুনরাবৃত্তি করেন, তখন সেই গোষ্ঠীকে পারমাণবিক করা অকার্যকর যেহেতু সেই গোষ্ঠীর সমস্ত ব্যাকট্র্যাকিং অবস্থানগুলি প্রতিটি পুনরাবৃত্তিতে মুছে ফেলা হয়। সুতরাং লেখার (?>[^)(]+|(?R))*+চেয়ে লেখাই সমান (?:[^)(]+|(?R))*+। পরের প্যাটার্নের জন্য একই জিনিস। অনিবন্ধিত সংস্করণ সম্পর্কে, আপনি এখানে একটি অধিকারী পরিমাণ [^)(]*+রাখতে পারেন: ব্যাকট্র্যাকিং রোধ করতে (কোনও বন্ধনী বন্ধনী না থাকলে ক্ষেত্রে)।
ক্যাসিমির এবং হিপপলিট 21

রুবি ১.৯ প্যাটার্ন সম্পর্কে, (...(..)..(..)..(..)..(..)..)সাবজেক্ট স্ট্রিংয়ে পুনরাবৃত্তি হওয়া গ্রুপটিকে পারমাণবিক (যেখানে অনেক নেস্টেড প্যারেনেসিস রয়েছে তার সীমিত আগ্রহ রয়েছে ) পরিবর্তে, আপনি একটি সাধারণ অ-ক্যাপচারিং গ্রুপ ব্যবহার করতে পারেন এবং সমস্তকে একটি পারমাণবিক গ্রুপে সংযুক্ত করতে পারেন: (?>(?:[^)(]+|\g<1>)*)( এটি হ'ল একটি অধিকারী কোয়ান্টিফায়ারের মতো আচরণ করে)। রুবি ২.x-এ, অধিকারী কোয়ান্টিফায়ার উপলব্ধ।
ক্যাসিমির এবং হিপপলিট

@ ক্যাসিমিরেট হিপপলিট আপনাকে ধন্যবাদ! আমি পিসিআরই প্যাটার্নগুলিকে সামঞ্জস্য করেছি এবং রুবি ১.৯ এর জন্য, আপনি কি পুরো প্যাটার্নটি এইরকম হতে চান ? নিজেকে আপডেট করতে নির্দ্বিধায় দয়া করে। আপনি কী বলতে চাইছেন তা আমি বুঝতে পেরেছি তবে অনেক উন্নতি হয়েছে কিনা তা নিশ্চিত not
বোবল বুদবুদ

117

আপনি রেজেক্স পুনরাবৃত্তি ব্যবহার করতে পারেন :

\(([^()]|(?R))*\)

3
একটি উদাহরণ এখানে সত্যিই দরকারী হবে, আমি এটি "(1, (2, 3)) (4, 5)" এর মতো কাজ করতে পারি না।
অ্যান্ডি হেডেন

4
@ অ্যান্ডি হেডেন এর কারণ এটি "(1, (2, 3)) (4, 5)" স্থানের সাথে দুটি গ্রুপ পৃথক করেছে। বিশ্বব্যাপী পতাকা: / (([(^ ()) | ((আরআর))) *) / জি সহ আমার রিজেক্সট ব্যবহার করুন। এখানে অনলাইনে পরীক্ষা দেওয়া হচ্ছে: regex101.com/r/lF0fI1/1
rogal111

1
আমি এই সম্পর্কে গত সপ্তাহে একটি প্রশ্ন জিজ্ঞাসা করেছি stackoverflow.com/questions/26385984/recursive-pattern-in-regex
অ্যান্ডি হেডেন

7
.NET 4.5 আমি এই প্যাটার্ন জন্য নিম্নলিখিত ত্রুটির পাবেন: Unrecognized grouping construct
Nam

3
অসাধারণ! এটি রেগেক্সের দুর্দান্ত বৈশিষ্ট্য। প্রকৃতপক্ষে প্রশ্নের উত্তর দেওয়ার একমাত্র ব্যক্তি হওয়ার জন্য আপনাকে ধন্যবাদ। এছাড়াও, সেই regex101 সাইটটি মিষ্টি।
অ্যান্ড্রু

28
[^\(]*(\(.*\))[^\)]*

[^\(]*স্ট্রিংয়ের শুরুতে খোলার ব্র্যাকেট নয় এমন সমস্ত কিছুর সাথে মেলে (\(.*\)), বন্ধনীগুলিতে আবদ্ধ প্রয়োজনীয় স্ট্রিংগুলি ক্যাপচার করে এবং [^\)]*স্ট্রিংয়ের শেষে বন্ধ হওয়া বন্ধনী নয় এমন সমস্ত কিছু মেলে। নোট করুন যে এই অভিব্যক্তিটি বন্ধনীগুলির সাথে মিলের চেষ্টা করে না; একটি সাধারণ পার্সার ( দেহমানের উত্তর দেখুন ) এর জন্য আরও উপযুক্ত হবে।


ক্লাসের ভিতরে বন্ধনীটি পালাতে হবে না। এটি অভ্যন্তর থেকে কোনও মেটাচার্যাক্ট নয়।
হোসে লিয়াল

10
"টেক্সট (পাঠ্য) পাঠ্য (পাঠ্য) পাঠ্য" রিটার্নিং "(পাঠ্য) পাঠ্য (পাঠ্য)" এর মতো কোনও কিছুর বিরুদ্ধে এই এক্সপ্রেস ব্যর্থ। নিয়মিত এক্সপ্রেশন ব্র্যাকেট গণনা করতে পারে না।
খ্রিস্টান ক্লাউজার

17
(?<=\().*(?=\))

আপনি যদি দুটি ম্যাচিংয়ের প্রথম বন্ধনীর মধ্যে পাঠ্য নির্বাচন করতে চান , আপনি নিয়মিত প্রকাশের সাথে ভাগ্যের বাইরে। এটি অসম্ভব (*)

এই রেজেক্সটি আপনার স্ট্রিংয়ের প্রথম প্রারম্ভিক এবং শেষ বন্ধক প্রথম বন্ধনের মধ্যবর্তী পাঠ্যটি কেবল ফেরত দেয়।


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


"<=" এবং "=" চিহ্নগুলি কী বোঝায়? এই এক্সপ্রেশন লক্ষ্যবস্তু কি regexp ইঞ্জিন?
খ্রিস্টান ক্লাউজার

1
এটি চেহারা-আশেপাশের, বা আরও সঠিকভাবে "শূন্য প্রস্থের চেহারা-এগিয়ে / চেহারা-পিছনে জোর দেওয়া"। বেশিরভাগ আধুনিক রেজেক্স ইঞ্জিন তাদের সমর্থন করে।
তোমালাক

ওপির উদাহরণ অনুসারে, তিনি ম্যাচে সবচেয়ে বাহ্যিক পেরেনকে অন্তর্ভুক্ত করতে চান। এই রেজেক্স তাদের ফেলে দেয়।
অ্যালান মুর

1
@ অ্যালান এম: আপনি ঠিক বলেছেন। তবে প্রশ্নের পাঠ্য অনুসারে, তিনি বাইরেরতম পেরেনগুলির মধ্যে সবকিছু চান wants আপনার পছন্দ চয়ন করুন। তিনি বলেছিলেন যে তিনি ঘণ্টার পর ঘণ্টা চেষ্টা করে যাচ্ছেন, তাই "বাহ্যিকতম পেরেন সহ সমস্ত কিছুই" উদ্দেশ্য হিসাবে বিবেচনা করেননি, কারণ এটি এত তুচ্ছ: "(। *)"।
টমলক

3
@ ঘায়েস এর উত্তরটি ২০০৯ সাল থেকে এসেছে That এটি অনেক দিন আগে; নিয়মিত এক্সপ্রেশন ইঞ্জিনগুলি যা কিছুটা পুনরাবৃত্তি করার অনুমতি দেয় তারা এখনকার চেয়ে বেশি অস্বাভাবিক হয়ে উঠেছে (এবং তারা এখনও বেশ অস্বাভাবিক)। আমি আমার উত্তরে এটি উল্লেখ করব।
তোমালক

14

এই উত্তরটি কেন এই কাজের জন্য নিয়মিত প্রকাশগুলি সঠিক সরঞ্জাম নয় তার তাত্ত্বিক সীমাবদ্ধতার ব্যাখ্যা দেয়।


নিয়মিত প্রকাশগুলি এটি করতে পারে না।

নিয়মিত এক্সপ্রেশন হিসাবে পরিচিত একটি কম্পিউটিং মডেল উপর ভিত্তি করে Finite State Automata (FSA)। নামটি ইঙ্গিত দেয়, একজন FSAকেবলমাত্র বর্তমান অবস্থা মনে করতে পারে, এর পূর্ববর্তী রাজ্যগুলি সম্পর্কে কোনও তথ্য নেই।

এফএসএ

উপরের চিত্রটিতে, এস 1 এবং এস 2 দুটি রাজ্য যেখানে এস 1 শুরু এবং চূড়ান্ত পদক্ষেপ। সুতরাং আমরা যদি স্ট্রিং দিয়ে চেষ্টা করি 0110তবে রূপান্তরটি নীচে চলে যায়:

      0     1     1     0
-> S1 -> S2 -> S2 -> S2 ->S1

উপরোক্ত ধাপগুলি সালে, যখন আমরা দ্বিতীয় হয় S2পার্স পর অর্থাত 01এর 0110, এফএসএ পূর্ববর্তী সম্পর্কে কোন তথ্য আছে 001যেমন কেবলমাত্র বর্তমান রাষ্ট্রীয় ও পরবর্তী ইনপুট প্রতীক মনে করতে পারেন।

উপরের সমস্যায়, খোলার প্রথম বন্ধনী সম্পর্কে আমাদের জানতে হবে; এর অর্থ এটি কোনও স্থানে সংরক্ষণ করতে হবে । কিন্তু যেহেতু FSAsএটি না করা যায়, তাই নিয়মিত প্রকাশ করা যায় না।

তবে এই কাজটি করার জন্য একটি অ্যালগরিদম লেখা যেতে পারে। অ্যালগরিদম সাধারণত অধীনে হয় Pushdown Automata (PDA)PDAউপরের এক স্তর FSA। পিডিএতে অতিরিক্ত কিছু তথ্য সঞ্চয় করার জন্য একটি অতিরিক্ত স্ট্যাক রয়েছে। উপরের সমস্যা সমাধানের জন্য পিডিএ ব্যবহার করা যেতে পারে, কারণ আমরা ' push' স্ট্যাকের খোলার প্রথম বন্ধনী এবং ' pop' একবার আমরা যখন ক্লোজিং বন্ধনীর মুখোমুখি হই। যদি শেষে, স্ট্যাক খালি থাকে, তবে বন্ধনী খোলা এবং বন্ধনীর প্রথম ম্যাচ বন্ধ করুন। অন্যথায় না।


ধাক্কা এবং পপ regexp মধ্যে সম্ভব stackoverflow.com/questions/17003799/... regular-expressions.info/balancing.html
মার্কো

1
এখানে বেশ কয়েকটি উত্তর রয়েছে, যা প্রমান করে, এটি সম্ভব।
জিও হার্নেক

1
@ মার্কো এই উত্তরটি তাত্ত্বিক দৃষ্টিকোণে নিয়মিত প্রকাশের বিষয়ে কথা বলে। এখন অনেকগুলি রিজেক্স ইঞ্জিন কেবল এই তাত্ত্বিক মডেলের উপর নির্ভর করে না এবং কাজটি করার জন্য কিছু অতিরিক্ত মেমরি ব্যবহার করে!
musibs

@ জিৎহর্নেক: এগুলি কঠোর অর্থে নিয়মিত প্রকাশ নয়: ক্লিনের দ্বারা নিয়মিত প্রকাশ হিসাবে সংজ্ঞায়িত হয় না । কিছু নিয়মিত এক্সপ্রেশন ইঞ্জিন প্রকৃতপক্ষে কিছু অতিরিক্ত ক্ষমতা প্রয়োগ করেছে, কেবলমাত্র নিয়মিত ভাষার চেয়ে পার্স করে তোলে ।
উইলেম ভ্যান অনসেম

12

নেট নিয়মিত এক্সপ্রেশন ব্যবহার করে এটি করা সম্ভব, তবে এটি তুচ্ছ নয়, তাই মনোযোগ দিয়ে পড়ুন।

আপনি এখানে একটি সুন্দর নিবন্ধ পড়তে পারেন । আপনার নেট। নিয়মিত প্রকাশ করতে হবে read আপনি এখানে পড়া শুরু করতে পারেন ।

অ্যাঙ্গেল বন্ধনী <>ব্যবহার করা হয়েছিল কারণ তাদের পালানোর প্রয়োজন নেই।

নিয়মিত অভিব্যক্তিটি এরকম দেখাচ্ছে:

<
[^<>]*
(
    (
        (?<Open><)
        [^<>]*
    )+
    (
        (?<Close-Open>>)
        [^<>]*
    )+
)*
(?(Open)(?!))
>

4

এটিই চূড়ান্ত রেজেক্স:

\(
(?<arguments> 
(  
  ([^\(\)']*) |  
  (\([^\(\)']*\)) |
  '(.*?)'

)*
)
\)

উদাহরণ:

input: ( arg1, arg2, arg3, (arg4), '(pip' )

output: arg1, arg2, arg3, (arg4), '(pip'

নোট করুন যে '(pip'স্ট্রিং হিসাবে সঠিকভাবে পরিচালিত হয়। (নিয়ন্ত্রকের চেষ্টা করা হয়েছে: http://sourceforge.net/projects/regulator/ )


4

আমি এই কাজটি করতে সহায়তা করার জন্য ভারসাম্যযুক্ত নামে একটি সামান্য জাভাস্ক্রিপ্ট লাইব্রেরি লিখেছি । আপনি এটি করে এটি সম্পাদন করতে পারেন

balanced.matches({
    source: source,
    open: '(',
    close: ')'
});

আপনি এমনকি প্রতিস্থাপন করতে পারেন:

balanced.replacements({
    source: source,
    open: '(',
    close: ')',
    replace: function (source, head, tail) {
        return head + source + tail;
    }
});

এখানে আরও জটিল এবং ইন্টারেক্টিভ উদাহরণ জেএসফিডাল


4

বুদবুদ বুবলীর উত্তরে যুক্ত করা হচ্ছে , এমন আরও রেইগেক্স স্বাদ রয়েছে যেখানে পুনরাবৃত্ত কনস্ট্রাক্টস সমর্থিত।

অ্যাপ্লিকেশন Lua

ব্যবহারের %b()( %b{}/ %b[]কোঁকড়া ধনুর্বন্ধনী জন্য / বর্গাকার বন্ধনী):

পার্ল 6 :

অ-ওভারল্যাপিং একাধিক ভারসাম্য প্রথম বন্ধনী মেলে:

my regex paren_any { '(' ~ ')' [ <-[()]>+ || <&paren_any> ]* }
say "Extract (a(b)c) and ((d)f(g))" ~~ m:g/<&paren_any>/;
# => (「(a(b)c)」 「((d)f(g))」)

একাধিক ভারসাম্য বন্ধনী ম্যাচ ওভারল্যাপিং:

say "Extract (a(b)c) and ((d)f(g))" ~~ m:ov:g/<&paren_any>/;
# => (「(a(b)c)」 「(b)」 「((d)f(g))」 「(d)」 「(g)」)

ডেমো দেখুন ।

পাইথন reনন-রেজেক্স সমাধান

ভারসাম্য প্রথম বন্ধনীগুলির মধ্যে কীভাবে এক্সপ্রেশন পেতে যায় তার জন্য পোকের উত্তর দেখুন ।

জাভা কাস্টমাইজেবল নন-রেজেক্স সমাধান

জাভাতে একক চরিত্রের আক্ষরিক ডিলিমিটারগুলিকে মঞ্জুরি দেওয়ার জন্য এখানে একটি অনুকূলিতকরণযোগ্য সমাধান দেওয়া হয়েছে:

public static List<String> getBalancedSubstrings(String s, Character markStart, 
                                 Character markEnd, Boolean includeMarkers) 

{
        List<String> subTreeList = new ArrayList<String>();
        int level = 0;
        int lastOpenDelimiter = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == markStart) {
                level++;
                if (level == 1) {
                    lastOpenDelimiter = (includeMarkers ? i : i + 1);
                }
            }
            else if (c == markEnd) {
                if (level == 1) {
                    subTreeList.add(s.substring(lastOpenDelimiter, (includeMarkers ? i + 1 : i)));
                }
                if (level > 0) level--;
            }
        }
        return subTreeList;
    }
}

নমুনা ব্যবহার:

String s = "some text(text here(possible text)text(possible text(more text)))end text";
List<String> balanced = getBalancedSubstrings(s, '(', ')', true);
System.out.println("Balanced substrings:\n" + balanced);
// => [(text here(possible text)text(possible text(more text)))]

এটি একাধিক ম্যাচের সাথে কাজ করে এমন প্রমাণের জন্য একটি অনলাইন জাভা ডেমো দেখুন ।
উইক্টর স্ট্রিবিউউ


3

আপনার প্রথম এবং শেষ বন্ধনী প্রয়োজন। এর মতো কিছু ব্যবহার করুন:

str.indexOf ('(')) - এটি আপনাকে প্রথম উপস্থিতি দেবে

str.lastIndexOf ( ')'); - সর্বশেষ

সুতরাং আপনার মাঝে একটি স্ট্রিং দরকার,

String searchedString = str.substring(str1.indexOf('('),str1.lastIndexOf(')');

1
"""
Here is a simple python program showing how to use regular
expressions to write a paren-matching recursive parser.

This parser recognises items enclosed by parens, brackets,
braces and <> symbols, but is adaptable to any set of
open/close patterns.  This is where the re package greatly
assists in parsing. 
"""

import re


# The pattern below recognises a sequence consisting of:
#    1. Any characters not in the set of open/close strings.
#    2. One of the open/close strings.
#    3. The remainder of the string.
# 
# There is no reason the opening pattern can't be the
# same as the closing pattern, so quoted strings can
# be included.  However quotes are not ignored inside
# quotes.  More logic is needed for that....


pat = re.compile("""
    ( .*? )
    ( \( | \) | \[ | \] | \{ | \} | \< | \> |
                           \' | \" | BEGIN | END | $ )
    ( .* )
    """, re.X)

# The keys to the dictionary below are the opening strings,
# and the values are the corresponding closing strings.
# For example "(" is an opening string and ")" is its
# closing string.

matching = { "(" : ")",
             "[" : "]",
             "{" : "}",
             "<" : ">",
             '"' : '"',
             "'" : "'",
             "BEGIN" : "END" }

# The procedure below matches string s and returns a
# recursive list matching the nesting of the open/close
# patterns in s.

def matchnested(s, term=""):
    lst = []
    while True:
        m = pat.match(s)

        if m.group(1) != "":
            lst.append(m.group(1))

        if m.group(2) == term:
            return lst, m.group(3)

        if m.group(2) in matching:
            item, s = matchnested(m.group(3), matching[m.group(2)])
            lst.append(m.group(2))
            lst.append(item)
            lst.append(matching[m.group(2)])
        else:
            raise ValueError("After <<%s %s>> expected %s not %s" %
                             (lst, s, term, m.group(2)))

# Unit test.

if __name__ == "__main__":
    for s in ("simple string",
              """ "double quote" """,
              """ 'single quote' """,
              "one'two'three'four'five'six'seven",
              "one(two(three(four)five)six)seven",
              "one(two(three)four)five(six(seven)eight)nine",
              "one(two)three[four]five{six}seven<eight>nine",
              "one(two[three{four<five>six}seven]eight)nine",
              "oneBEGINtwo(threeBEGINfourENDfive)sixENDseven",
              "ERROR testing ((( mismatched ))] parens"):
        print "\ninput", s
        try:
            lst, s = matchnested(s)
            print "output", lst
        except ValueError as e:
            print str(e)
    print "done"

0

উত্তরটি ব্র্যাকেটের মিলের সেটগুলির সাথে মিলানোর প্রয়োজন কিনা, বা ইনপুট পাঠ্যের কেবল সর্বশেষে প্রথম উন্মুক্ত হওয়া উচিত তার উপর নির্ভর করে।

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

যদি এটি কেবল প্রথম উন্মুক্ত হয় তবে শেষ দেখুন @ জ্যাচ

আপনি কী হতে চান তা স্থির করুন:

abc ( 123 ( foobar ) def ) xyz ) ghij

এই ক্ষেত্রে আপনার কোডটি কী মিলবে তা আপনাকে সিদ্ধান্ত নিতে হবে।


3
এটি কোনও উত্তর নয়।
অ্যালান মুর

হ্যাঁ, প্রশ্নের পরিবর্তনের দাবিটি একটি মন্তব্য হিসাবে দেওয়া উচিত,
গাংনাস

0

যেহেতু জেএস রেজেেক্স পুনরাবৃত্তির ম্যাচ সমর্থন করে না, আমি ভারসাম্যপূর্ণ বন্ধনী ম্যাচিং কাজ করতে পারি না।

সুতরাং এটি লুপ সংস্করণের জন্য একটি সহজ জাভাস্ক্রিপ্ট যা "পদ্ধতি (আরগ)" স্ট্রিংকে অ্যারে করে তোলে

push(number) map(test(a(a()))) bass(wow, abc)
$$(groups) filter({ type: 'ORGANIZATION', isDisabled: { $ne: true } }) pickBy(_id, type) map(test()) as(groups)
const parser = str => {
  let ops = []
  let method, arg
  let isMethod = true
  let open = []

  for (const char of str) {
    // skip whitespace
    if (char === ' ') continue

    // append method or arg string
    if (char !== '(' && char !== ')') {
      if (isMethod) {
        (method ? (method += char) : (method = char))
      } else {
        (arg ? (arg += char) : (arg = char))
      }
    }

    if (char === '(') {
      // nested parenthesis should be a part of arg
      if (!isMethod) arg += char
      isMethod = false
      open.push(char)
    } else if (char === ')') {
      open.pop()
      // check end of arg
      if (open.length < 1) {
        isMethod = true
        ops.push({ method, arg })
        method = arg = undefined
      } else {
        arg += char
      }
    }
  }

  return ops
}

// const test = parser(`$$(groups) filter({ type: 'ORGANIZATION', isDisabled: { $ne: true } }) pickBy(_id, type) map(test()) as(groups)`)
const test = parser(`push(number) map(test(a(a()))) bass(wow, abc)`)

console.log(test)

ফলাফল যেমন হয়

[ { method: 'push', arg: 'number' },
  { method: 'map', arg: 'test(a(a()))' },
  { method: 'bass', arg: 'wow,abc' } ]
[ { method: '$$', arg: 'groups' },
  { method: 'filter',
    arg: '{type:\'ORGANIZATION\',isDisabled:{$ne:true}}' },
  { method: 'pickBy', arg: '_id,type' },
  { method: 'map', arg: 'test()' },
  { method: 'as', arg: 'groups' } ]

0

যদিও এতগুলি উত্তর একরকম আকারে এটি উল্লেখ করে রেগেক্স পুনরাবৃত্ত মিলে যাওয়া সমর্থন করে না ইত্যাদি, এটির প্রাথমিক কারণটি থিওরি অফ কম্পিউটেশনের মূলের মধ্যে রয়েছে lies

ফর্মের ভাষা {a^nb^n | n>=0} is not regular। রেগেক্স কেবলমাত্র সেই ভাষাগুলির সাথে মেলে যা ভাষার নিয়মিত সেটগুলির অংশ হয়ে যায়।

আরও এখানে পড়ুন


0

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

def extract_code(data):
    """ returns an array of code snippets from a string (data)"""
    start_pos = None
    end_pos = None
    count_open = 0
    count_close = 0
    code_snippets = []
    for i,v in enumerate(data):
        if v =='{':
            count_open+=1
            if not start_pos:
                start_pos= i
        if v=='}':
            count_close +=1
            if count_open == count_close and not end_pos:
                end_pos = i+1
        if start_pos and end_pos:
            code_snippets.append((start_pos,end_pos))
            start_pos = None
            end_pos = None

    return code_snippets

আমি এটি একটি পাঠ্য ফাইল থেকে কোড স্নিপেটগুলি নিষ্কাশন করতে ব্যবহার করেছি।


0

নেস্টেড নিদর্শনগুলি আসে এমন পরিস্থিতিতে আমিও আটকে ছিলাম।

নিয়মিত এক্সপ্রেশন উপরোক্ত সমস্যাটি সমাধান করার জন্য সঠিক জিনিস। নিচে প্যাটার্ন ব্যবহার করুন

'/(\((?>[^()]+|(?1))*\))/'


-1

এটি কারওর পক্ষে কার্যকর হতে পারে:

জাভাস্ক্রিপ্টে ফাংশন স্ট্রিং (নেস্টেড স্ট্রাকচার সহ) থেকে প্যারামিটারগুলি পার্স করুন

মিল কাঠামো যেমন:
ফাংশন স্ট্রিং থেকে প্যারামিটারগুলি পার্স করুন

  • বন্ধনী, বর্গাকার বন্ধনী, বন্ধনী, একক এবং ডাবল উদ্ধৃতি মেলে

এখানে আপনি ক্রিয়াকলাপিত জেনারেটেড রিজেক্সট দেখতে পাচ্ছেন

/**
 * get param content of function string.
 * only params string should be provided without parentheses
 * WORK even if some/all params are not set
 * @return [param1, param2, param3]
 */
exports.getParamsSAFE = (str, nbParams = 3) => {
    const nextParamReg = /^\s*((?:(?:['"([{](?:[^'"()[\]{}]*?|['"([{](?:[^'"()[\]{}]*?|['"([{][^'"()[\]{}]*?['")}\]])*?['")}\]])*?['")}\]])|[^,])*?)\s*(?:,|$)/;
    const params = [];
    while (str.length) { // this is to avoid a BIG performance issue in javascript regexp engine
        str = str.replace(nextParamReg, (full, p1) => {
            params.push(p1);
            return '';
        });
    }
    return params;
};

এটি ওপি প্রশ্নের সম্পূর্ণরূপে সম্বোধন করে না তবে আমি নীস্ট স্ট্রাকচার রিজেক্সএক্স অনুসন্ধান করতে এখানে আসার কিছু লোকের পক্ষে এটি কার্যকর হতে পারে।

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