libzypp  17.28.8
Regex.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <cstdio>
13 #include <cstdarg>
14 
15 #include <iostream>
16 
17 #include <zypp-core/base/Regex.h>
18 #include <zypp-core/base/StringV.h>
19 
20 using namespace zypp;
21 using namespace zypp::str;
22 
24 : m_flags( match_extended )
25 {}
26 
27 regex::regex( const std::string & str, int flags )
28 { assign( str, flags ); }
29 
31 {
32  if ( m_valid )
33  regfree( &m_preg );
34 }
35 
36 void regex::assign( const std::string & str, int flags )
37 {
38  if ( m_valid )
39  regfree( &m_preg );
40 
41  m_valid = false;
42  m_str = str;
43  m_flags = flags;
44 
45  static constexpr int normal = 1<<16; // deprecated legacy, use match_extended
46  if ( flags & normal ) flags &= ~normal;
47  if ( (flags & rxdefault) != rxdefault ) flags |= rxdefault; // always enforced (legacy)
48 
49  if ( int err = regcomp( &m_preg, str.c_str(), flags ) ) {
50  char errbuff[100];
51  regerror( err, &m_preg, errbuff, sizeof(errbuff) );
52  ZYPP_THROW( regex_error(std::string(errbuff)) );
53  }
54  m_valid = true;
55 }
56 
57 bool regex::matches( const char* s, smatch & matches, int flags ) const
58 {
59  if ( m_valid ) {
60  const auto possibleMatchCount = m_preg.re_nsub + 1;
61  matches.pmatch.resize( possibleMatchCount );
62  memset( matches.pmatch.data(), -1, sizeof( regmatch_t ) * ( possibleMatchCount ) );
63 
64  if ( s && !regexec( &m_preg, s, matches.pmatch.size(), matches.pmatch.data(), flags ) ) {
65  matches.match_str = s;
66  return true; // good match
67  }
68  }
69  // Here: no match
70  matches.pmatch.clear();
71  matches.match_str.clear();
72  return false;
73 }
74 
75 bool regex::matches( const char* s ) const
76 {
77  return m_valid && s && !regexec( &m_preg, s, 0, NULL, 0 );
78 }
79 
80 bool zypp::str::regex_match( const char* s, smatch& matches, const regex& regex )
81 { return regex.matches( s, matches ); }
82 
83 bool zypp::str::regex_match( const char* s, const regex& regex )
84 { return regex.matches( s ); }
85 
87 {}
88 
89 std::string smatch::operator[](unsigned i) const
90 {
91  if ( i < pmatch.size() && pmatch[i].rm_so != -1 )
92  return match_str.substr( pmatch[i].rm_so, pmatch[i].rm_eo-pmatch[i].rm_so );
93 
94  return std::string();
95 }
96 
98 { return( i < pmatch.size() && pmatch[i].rm_so != -1 ? pmatch[i].rm_so : std::string::npos ); }
99 
101 { return( i < pmatch.size() && pmatch[i].rm_so != -1 ? pmatch[i].rm_eo : std::string::npos ); }
102 
104 { return( i < pmatch.size() && pmatch[i].rm_so != -1 ? pmatch[i].rm_eo-pmatch[i].rm_so : std::string::npos ); }
105 
106 unsigned smatch::size() const
107 {
108  unsigned matches = unsigned(-1);
109  // Get highest (pmatch[i].rm_so != -1). Just looking for the 1st
110  // (pmatch[i].rm_so == -1) is wrong as optional mayches "()?"
111  // may be embeded.
112  for ( unsigned i = 0; i < pmatch.size(); ++i )
113  {
114  if ( pmatch[i].rm_so != -1 )
115  matches = i;
116  }
117  return ++matches;
118 }
119 
120 std::string zypp::str::regex_substitute( const std::string &s, const regex &regex, const std::string &replacement, bool global )
121 {
122  std::string result;
123  strv::splitRx( s, regex, [&result,&replacement,global]( std::string_view w, unsigned, bool last ) {
124  result += w;
125  if ( !last )
126  result += replacement;
127  return global;
128  });
129  return result;
130 }
Regular expression.
Definition: Regex.h:95
regex_t m_preg
Definition: Regex.h:148
std::string m_str
Definition: Regex.h:146
@ rxdefault
These are enforced even if you don't pass them as flag argument.
Definition: Regex.h:103
bool m_valid
Definition: Regex.h:149
void assign(const std::string &s, int flags)
Definition: Regex.cc:36
bool matches(const char *s, str::smatch &matches, int flags=none) const
Definition: Regex.cc:57
Regular expression match result.
Definition: Regex.h:168
unsigned size() const
Definition: Regex.cc:106
std::string::size_type end(unsigned i) const
End index of subexpression i in match_str (or std::string::npos)
Definition: Regex.cc:100
std::string::size_type begin(unsigned i) const
Begin index of subexpression i in match_str (or std::string::npos)
Definition: Regex.cc:97
std::string operator[](unsigned i) const
Definition: Regex.cc:89
std::string match_str
Definition: Regex.h:185
std::vector< regmatch_t > pmatch
Definition: Regex.h:186
String related utilities and Regular expression matching.
SolvableIdType size_type
Definition: PoolMember.h:126
String related utilities and Regular expression matching.
Definition: PurgeKernels.h:18
std::string regex_substitute(const std::string &s, const regex &regex, const std::string &replacement, bool global=true)
Replaces the matched regex with the string passed in replacement.
Definition: Regex.cc:120
bool regex_match(const std::string &s, smatch &matches, const regex &regex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
Definition: Regex.h:70
Exception regex_error
Definition: Regex.h:54
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392