নিয়মিত এক্সপ্রেশন সম্পর্কে জিসিসি 4.8 বা এর আগের বগি কি?


101

আমি সি ++ 11 কোডের কোডে স্টাডি :: রেজেক্স ব্যবহার করার চেষ্টা করছি, তবে দেখা যাচ্ছে যে সমর্থনটি কিছুটা বগি। একটি উদাহরণ:

#include <regex>
#include <iostream>

int main (int argc, const char * argv[]) {
    std::regex r("st|mt|tr");
    std::cerr << "st|mt|tr" << " matches st? " << std::regex_match("st", r) << std::endl;
    std::cerr << "st|mt|tr" << " matches mt? " << std::regex_match("mt", r) << std::endl;
    std::cerr << "st|mt|tr" << " matches tr? " << std::regex_match("tr", r) << std::endl;
}

আউটপুট:

st|mt|tr matches st? 1
st|mt|tr matches mt? 1
st|mt|tr matches tr? 0

যখন gcc (ম্যাকপোর্টস gcc47 4.7.1_2) 4.7.1 এর সাথে সংকলিত হয়, এর সাথে হয়

g++ *.cc -o test -std=c++11
g++ *.cc -o test -std=c++0x

অথবা

g++ *.cc -o test -std=gnu++0x

তদ্ব্যতীত, আমার কাছে কেবল দুটি বিকল্প নিদর্শন থাকলে রেজেক্স ভালভাবে কাজ করে, উদাহরণস্বরূপ st|mt, দেখে মনে হচ্ছে এটি কোনও কারণে শেষেরটির সাথে মেলে না। কোডটি অ্যাপল এলএলভিএম সংকলকটির সাথে ভালভাবে কাজ করে।

সমস্যাটি কীভাবে সমাধান করবেন সে সম্পর্কে কোনও ধারণা?

আপডেট একটি সম্ভাব্য সমাধান, একাধিক বিকল্প বাস্তবায়ন যেমন গ্রুপ ব্যবহার করা (st|mt)|tr


9
হ্যাঁ libstdc ++ এর <regex>সমর্থন অসম্পূর্ণ। আমরা আপনাকে কী সাহায্য করতে পারি?
কেনেটিএম

10
Libstdcregex ++ এ স্ট্যাটাসের জন্য , gcc.gnu.org/onlinesocs/libstdc++/manual/…
একাটামুর

51
গুরুতরভাবে যদিও, কে যদিও এই "যে মিথ্যা প্রত্যাবর্তন" করে কেবল regex_search একটি বাস্তবায়ন শিপিং একটি ভাল ধারণা ছিল? "ওহ, আমরা এটি নথিভুক্ত করেছি" মনে হচ্ছে এটি একটি দুর্বল জবাব।
পল রুবেল

4
@ একে ৪74৪৯৯: এটি কোনও ত্রুটি নয়। এটি কেবল সম্পূর্ণ বাস্তবায়নহীন। যদিও এই প্রশ্নটি কতবার দেখায় তা উদ্বেগজনক, বিশেষত যেহেতু <regex>গত ৩-৪ বছরে libstdc ++ সম্পর্কে কিছুই পরিবর্তিত হয়নি (যেমন: এটি প্রয়োগযোগ্য নয়)।
রুবেনভবি

5
@ কিথথম্পসন, যদিও এটি সত্য যে লাইবস্টাডিসি <regex>++ (জিসিসি স্ট্যান্ডার্ড লাইব্রেরি) সরবরাহ করেছেন না gcc(সংকলক সম্মুখ প্রান্ত), এটি জিসিসির (প্রকল্প) অংশ part দেখুন "libstdc ++ - v3 GCC এর অংশ হিসাবে বিকাশিত এবং প্রকাশিত হয়েছে" । যদি আপনার ডিস্ট্রো এটিকে আলাদা প্যাকেজে বিভক্ত করতে পছন্দ করে তবে এটি জিসিসির সাথে কিছুই করার নয়।
জোনাথন ওয়াকলি

উত্তর:


168

<regex> জিসিসি ৪.৯.০ এ প্রয়োগ ও প্রকাশ করা হয়েছিল।

আপনার জিসিসির (পুরানো) সংস্করণে এটি প্রয়োগ করা হয়নি

যে প্রোটোটাইপ <regex>যখন জিসিসি এর সি ++ 0x সমর্থন সব ছিল কোড যোগ করা হয়েছিল অত্যন্ত পরীক্ষামূলক, প্রথম দিকে সি ট্র্যাকিং ++, 0x ড্রাফ্ট এবং মানুষ নিয়ে পরীক্ষা করতে জন্য উপলব্ধ করা হচ্ছে। এর ফলে লোকেদের সমস্যাগুলি খুঁজে পেতে ও স্ট্যান্ডার্ড কমিটির কাছে স্ট্যান্ডার্ড চূড়ান্ত হওয়ার আগে প্রতিক্রিয়া জানানো হয়েছিল। সেই সময় প্রচুর লোকেরা রক্তপাতের প্রান্ত বৈশিষ্ট্যগুলিতে অ্যাক্সেস পেয়ে অনেক কৃতজ্ঞ ছিলেন সি ++ 11 শেষ হওয়ার আগে এবং আরও অনেক সংকলক কোনও সহায়তা দেওয়ার আগে , এবং এই প্রতিক্রিয়াটি সত্যই সি ++ 11 উন্নত করতে সহায়তা করেছিল। এটি একটি গুড থিং টিএম ছিল

<regex>কোড একটি দরকারী রাজ্যের ছিল না, কিন্তু একটি কাজ-ইন-উন্নতি সময়ে কোডের অনেক অন্যান্য বিট মত যোগ করা হয়েছিল। এটি চেক ইন করা হয়েছিল এবং অন্যরা চাইলে তাদের সহযোগিতা করার জন্য উপলব্ধ করা হয়েছিল, শেষ পর্যন্ত এটি শেষ হবে এই উদ্দেশ্য নিয়ে।

এটি প্রায়শই কীভাবে ওপেন সোর্স কাজ করে: তাড়াতাড়ি প্রকাশ করুন, প্রায়শই প্রকাশ করুন - দুর্ভাগ্যক্রমে <regex>আমরা কেবল প্রাথমিক অংশ পেয়েছি এবং প্রায়শই অংশটি বাস্তবায়ন শেষ করে নি।

লাইব্রেরির বেশিরভাগ অংশই আরও সম্পূর্ণ ছিল এবং এখন প্রায় সম্পূর্ণ প্রয়োগ করা হয়েছে, তবে <regex>তা হয়নি, সুতরাং এটি যুক্ত হওয়ার পরে এটি একই অসম্পূর্ণ অবস্থায় থেকে যায়।

গুরুতরভাবে যদিও, কে যদিও এই "যে মিথ্যা প্রত্যাবর্তন" করে কেবল regex_search একটি বাস্তবায়ন শিপিং একটি ভাল ধারণা ছিল?

কয়েক বছর আগে এটি এতটা খারাপ ধারণা ছিল না, যখন সি ++ 0 এক্স এখনও প্রক্রিয়াধীন ছিল এবং আমরা প্রচুর আংশিক বাস্তবায়ন পাঠিয়েছি। কেউ মনে করেনি এটি এত দিন অব্যবহারযোগ্য থাকবে, পর্দার সংজ্ঞা সহকারে, সম্ভবত এটি অক্ষম করা উচিত ছিল এবং এটি সক্ষম করার জন্য ম্যাক্রো বা বিল্ট-টাইম বিকল্পের প্রয়োজন ছিল। তবে সেই জাহাজটি অনেক আগে যাত্রা করেছিল। থেকে রপ্তানি চিহ্ন আছে আগে থেকে libstdc ++। তাই গ্রন্থাগার যে Regex কোডের উপর নির্ভর করে, তাই কেবল এটি সরানোর (, বলে, জিসিসি 4.8) না তুচ্ছ হয়েছে।


12

বৈশিষ্ট্য সনাক্তকরণ

libstdc++সি প্রিপ্রোসেসর সংজ্ঞায়িত সহ বাস্তবায়ন বাস্তবায়িত হয় কিনা তা সনাক্ত করার জন্য এটি একটি স্নিপেট is

#include <regex>
#if __cplusplus >= 201103L &&                             \
    (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
        (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
         defined(_GLIBCXX_REGEX_STATE_LIMIT)           || \
             (defined(_GLIBCXX_RELEASE)                && \
             _GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif

ম্যাক্রো

  • _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMITমধ্যে সংজ্ঞায়িত করা bits/regex.tccহয়4.9.x
  • _GLIBCXX_REGEX_STATE_LIMITমধ্যে সংজ্ঞায়িত করা bits/regex_automatron.hহয়5+
  • _GLIBCXX_RELEASEএই উত্তরের7+ ফলাফল হিসাবে যুক্ত করা হয়েছিল এবং এটি জিসিসির প্রধান সংস্করণ

পরীক্ষামূলক

আপনি এটি জিসিসির সাথে এটি পরীক্ষা করতে পারেন:

cat << EOF | g++ --std=c++11 -x c++ - && ./a.out
#include <regex>

#if __cplusplus >= 201103L &&                             \
    (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
        (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
         defined(_GLIBCXX_REGEX_STATE_LIMIT)           || \
             (defined(_GLIBCXX_RELEASE)                && \
             _GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif

#include <iostream>

int main() {
  const std::regex regex(".*");
  const std::string string = "This should match!";
  const auto result = std::regex_search(string, regex);
#if HAVE_WORKING_REGEX
  std::cerr << "<regex> works, look: " << std::boolalpha << result << std::endl;
#else
  std::cerr << "<regex> doesn't work, look: " << std::boolalpha << result << std::endl;
#endif
  return result ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF

ফলাফল

বিভিন্ন সংকলকগুলির জন্য এখানে কিছু ফলাফল রয়েছে:


$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> doesn't work, look: false

$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ clang --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ ./a.out  # compiled with 'clang -lstdc++'
<regex> works, look: true

এখানে ড্রাগন হতে হবে

এটি সম্পূর্ণ অসমর্থিত এবং জিসিসি বিকাশকারীরা bits/regex*শিরোলেখগুলিতে প্রাইভেট ম্যাক্রো সনাক্তকরণের উপর নির্ভর করে । তারা যে কোনও সময় পরিবর্তন করতে এবং চলে যেতে পারে । আশা করা যায়, এগুলি বর্তমান 4.9.x, 5.x, 6.x রিলিজগুলিতে সরানো হবে না তবে তারা 7.x প্রকাশে যেতে পারে।

যদি জিসিসি বিকাশকারীরা #define _GLIBCXX_HAVE_WORKING_REGEX 1x.x রিলিজ অব্যাহত রেখে একটি (বা কিছু, হিন্ট নজ নজ) যুক্ত করে থাকে তবে এই স্নিপেটটি অন্তর্ভুক্ত করার জন্য আপডেট করা যেতে পারে এবং পরে জিসিসি প্রকাশগুলি উপরের স্নিপেটের সাথে কাজ করবে।

আমি যতদূর জানি, অন্যান্য সমস্ত সংকলকগুলির <regex>যখন __cplusplus >= 201103Lওয়াইএমএমভি হয় তবে একটি কাজ থাকে ।

স্পষ্টতই যদি কেউ শিরোনামের বাইরে _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMITবা _GLIBCXX_REGEX_STATE_LIMITম্যাক্রো সংজ্ঞায়িত করে তবে এটি সম্পূর্ণরূপে ভঙ্গ হবে stdc++-v3


খুব সুন্দর! আমি জিসিসি ৪.৯-এ নতুন যে একটি শিরোলেখ থেকে হেডার গার্ড ম্যাক্রো পরীক্ষা করার পরামর্শ দিচ্ছিলাম, তবে তাদের রক্ষী নেই: - G ম্যাক্রোগুলি জিসিসি 7 এর জন্য পরিবর্তন করছে না, তাত্ত্বিকভাবে তারা জিসিসির পক্ষে করতে পারত 8+, সুতরাং দয়া করে gcc.gnu.org/bugzilla এ বর্ধন অনুরোধ ফাইল _GLIBCXX_REGEX_IS_OK_NOW_KTHXBAIকরুন শিরোনামগুলির মতো এমন কিছু চেয়েছিলেন , যাতে এটি ভুলে যায় না - ধন্যবাদ!
জোনাথন ওয়াকলি

1
@JonathanWakely যুক্ত করেছেন 78905 । এটিকে কীভাবে বর্ধিত বাগে পরিণত করা যায় তা সম্পর্কে আমি নিশ্চিত নই তবে এটি এখন সিস্টেমে।
ম্যাট ক্লার্কসন

1

এই মুহুর্তে (g ++ (GCC) 4.9.2 এ std = c ++ 14 ব্যবহার করা) এখনও regex_match গ্রহণ করছে না।

এখানে এমন একটি দৃষ্টিভঙ্গি রয়েছে যা regex_match এর মতো কাজ করে তবে পরিবর্তে sregex_token_iterator ব্যবহার করে। এবং এটি g ++ নিয়ে কাজ করে।

string line="1a2b3c";
std::regex re("(\\d)");
std::vector<std::string> inVector{
    std::sregex_token_iterator(line.begin(), line.end(), re, 1), {}
};

//prints all matches
for(int i=0; i<inVector.size(); ++i)
    std::cout << i << ":" << inVector[i] << endl;

এটি 1 2 3 মুদ্রণ করবে

আপনি এখানে sregex_token_iterator রেফারেন্সটি পড়তে পারেন: http://en.cppreferences.com/w/cpp/regex/regex_token_iterator


1
"এই মুহুর্তে (জি ++ (জিসিসি) ৪.৯.২ এ স্টাডি = সি ++ ১৪ ব্যবহার করে) এখনও রেজেক্স_ম্যাচ গ্রহণ করছে না।" এটি সত্য নয়, আপনি সম্ভবত এটি ভুল ব্যবহার করছেন।
জোনাথন ওয়েকেলি

1
আপনার কোডটি "এমন একটি দৃষ্টিভঙ্গি নয় যা regex_match এর মতো কাজ করে" কারণ এই ফাংশনটি সাব স্ট্রিংয়ের সাথে সাব-স্ট্রিংগুলির সাথে মেলে না চেষ্টা করে, তাই আমি এখনও মনে করি আপনি এটি ভুল ব্যবহার করছেন। আপনি এটির সাহায্যে এটি করতে পারেন std::regex_search, দেখুন ভ্যান্ডবক্স.অর্গ
জোনাথন Wakely
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.