-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
281 lines (227 loc) · 18.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
<!DOCTYPE html>
<html lang="en-us">
<head>
<link rel="canonical" href="https://neurobin.org/projects/softwares/libs/jpcre2" />
<meta http-equiv="refresh" content="0;url=https://neurobin.org/projects/softwares/libs/jpcre2">
<script>
window.location.href = "http://neurobin.org/projects/softwares/libs/jpcre2"
</script>
<meta charset="UTF-8">
<title>jpcre2 by jpcre2</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<section class="page-header">
<h1 class="project-name">jpcre2</h1>
<h2 class="project-tagline">C++ wrapper of PCRE2 library</h2>
</section>
<section class="main-content">
<h1>
<a id="c-wrapper-for-several-utilities-of-pcre2-library" class="anchor" href="#c-wrapper-for-several-utilities-of-pcre2-library" aria-hidden="true"><span class="octicon octicon-link"></span></a>C++ wrapper for several utilities of PCRE2 Library</h1>
<p>PCRE2 is the name used for a revised API for the PCRE library, which is a set of functions, written in C, that implement regular expression pattern matching using the same syntax and semantics as Perl, with just a few differences. Some features that appeared in Python and the original PCRE before they appeared in Perl are also available using the Python syntax.</p>
<p>This provides some C++ wrapper functions to provide some useful utilities like regex match and regex replace.</p>
<h1>
<a id="requirements" class="anchor" href="#requirements" aria-hidden="true"><span class="octicon octicon-link"></span></a>Requirements:</h1>
<ol>
<li>C++ compiler with C++11 support.</li>
<li>pcre2 library (<code>version >=10.21</code>).</li>
</ol>
<p>If the required <code>pcre2</code> version is not available in the official channel, download <a href="https://github.com/jpcre2">my fork of the library from here</a>, Or use <a href="https://github.com/jpcre2/pcre2">this repository</a> which will always be kept compatible with <code>jpcre2</code>.</p>
<h1>
<a id="how-to" class="anchor" href="#how-to" aria-hidden="true"><span class="octicon octicon-link"></span></a>How To:</h1>
<h2>
<a id="how-to-compile" class="anchor" href="#how-to-compile" aria-hidden="true"><span class="octicon octicon-link"></span></a>How to compile:</h2>
<ol>
<li><p><code>#include</code> the <code>jpcre2.hpp</code> file in your program. </p></li>
<li><p>Compile with <code>pcre2</code> library linked and c++11 enabled.</p></li>
</ol>
<p><strong>Example:</strong></p>
<p>A simple <em>mycpp.cpp</em> file should be compiled with the following command with GCC.</p>
<div class="highlight highlight-source-shell"><pre>g++ -std=c++11 mycpp.cpp -lpcre2-8</pre></div>
<p><code>-lpcre1-8</code> should be changed to the actual library i.e for 16 bit code unit: <code>-lpcre2-16</code> and for 32 bit code unit: <code>-lpcre2-32</code>.</p>
<p>If your <code>pcre2</code> library is not in the standard library path, then add the path:</p>
<div class="highlight highlight-source-shell"><pre>g++ -std=c++11 mycpp.cpp -L/path/to/your/pcre2/library -lpcre2-8</pre></div>
<p><strong>Note that</strong> it requires the <code>pcre2</code> library installed in your system. If it is not already installed and linked in your compiler, you will need to link it with appropriate path and options.</p>
<h2>
<a id="how-to-code" class="anchor" href="#how-to-code" aria-hidden="true"><span class="octicon octicon-link"></span></a>How to code:</h2>
<ol>
<li>
First create a <code>Pcre2Regex</code> object. This object will hold the pattern, modifiers, compiled pattern, error and warning codes.
</li>
<ol>
<li>Each object for each regex pattern.
</li>
<li>Pattern and modifier can be initialized with constructor (<code>Pcre2Regex(pattern,modifier)</code>) or with member functions <code>setPattern()</code> and <code>setModifier()</code>.
Ex:<pre><code>
Pcre2Regex re("\\d\\w+","Sugi"); //Initialize pattern and modifier with constructor
re.setPattern("\\w\\S+"); //This sets the pattern
re.setModifier("g"); //This sets the modifier.
</code></pre>
</li>
<li>
N.B: Every time you change the pattern, you will need to recompile it and every time you change compile modifier, you will need to recompile the pattern to apply the change.
</li>
</ol>
<li>
Compile the pattern and catch any error exception:
<pre><code>
try{re.compile();} //This compiles the previously set pattern and modifier
catch(int e){/*Handle error*//*std::cout<<re.getErrorMessage(e)<<std::endl;*/}
try{re.compile("pattern","mgi");} //This compiles the pattern and modifier provided.
catch(int e){/*Handle error*//*std::cout<<re.getErrorMessage(e)<<std::endl;*/}
</code></pre>
</li>
<li>
Now you can perform match or replace against the pattern. Use the <code>match()</code> member function to preform regex match and the <code>replace()</code> member function to perform regex replace.
</li>
<ol>
<li>
<b>Match:</b> The <code>match()</code> member function takes the subject string and some specialized vectors (vectors of maps of substrings) as its arguments and a last argument to tell whether to match all or only the first. It puts the results in the maps of the vectors and returns true on successful match and false otherwise.
</li>
</ol>
</ol><ul>
<li>
Perform match and catch any error exception:
<pre><code>
try{re.match("I am a subject string",vec_num);}
catch(int e){/*Handle error*//*std::cout<<re.getErrorMessage(e)<<std::endl;*/}
//vec_num will be populated with numbered substrings.
</code></pre>
Access the substrings like this:
<pre><code>
for(int i=0;i<(int)vec_num.size();i++){
//This loop will iterate only once if find_all is false.
//i=0 is the first match found, i=1 is the second and so forth
for(auto const& ent : vec_num[i]){
//ent.first is the number/position of substring found
//ent.second is the substring itself
//when ent.first is 0, ent.second is the total match.
}
}
</code></pre>
</li>
<li>
Other variations of this function can be used to get named substrings and the position of named substrings. Simply pass the appropriate vectors in the match function:
<pre><code>
try{re.match("I am a subject string",vec_num,vec_nas,vec_nn);}
catch(int e){/*Handle error*//*std::cout<<re.getErrorMessage(e)<<std::endl;*/}
</code></pre>
And access the substrings by looping through the vectors and associated maps. The size of all three vectors are the same and they can be passed in any sequence (i.e the order of the vectors as arguments is not important).
</li>
</ul>
<b>Replace:</b> The <code>replace()</code> member function takes the subject string as first argument and replacement string as the second argument and two optional arguments (modifier and the size of the resultant string) and returns the resultant string after performing the replacement operation. If no modifier is passed an empty modifier is assumed.
<ul>
<li>
Perform replace and catch any error exception:
<pre><code>
try{re.replace("replace this string according to the pattern","with this string","mgi");}
catch(int e){/*Handle error*//*std::cout<<re.getErrorMessage(e)<<std::endl;*/}
//mgi is the modifier passed (multiline, global, case insensitive).
//Access substrings/captured groups with ${1234},$1234 (for numbered substrings) or ${name} (for named substrings)
</code></pre>
</li>
<li>
If you pass the size of the resultant string with the replace function, then make sure it will be enough to store the whole resultant replaced string, otherwise the internal replace function (<code>pcre2_substitute()</code>) will be called <i>twice</i> to adjust the size to hold the whole resultant string in order to avoid <code>PCRE2_ERROR_NOMEMORY</code> error. Two consecutive call of the same function may affect overall performance of your code.
</li>
</ul>
<h1>
<a id="insight" class="anchor" href="#insight" aria-hidden="true"><span class="octicon octicon-link"></span></a>Insight:</h1>
<h2>
<a id="namespaces" class="anchor" href="#namespaces" aria-hidden="true"><span class="octicon octicon-link"></span></a>Namespaces:</h2>
<ol>
<li>
<strong>jpcre2_utils :</strong> Some utility functions used by <code>jpcre2</code>.</li>
<li>
<strong>jpcre2 :</strong> This is the namespace you will be using in your code to access <code>jpcre2</code> classes and functions.</li>
</ol>
<h2>
<a id="classes" class="anchor" href="#classes" aria-hidden="true"><span class="octicon octicon-link"></span></a>Classes:</h2>
<ol>
<li>
<strong>Pcre2Regex :</strong> This is the main class which holds the key utilities of <code>jpcre2</code>. Every regex needs an object of this class.</li>
</ol>
<h2>
<a id="functions" class="anchor" href="#functions" aria-hidden="true"><span class="octicon octicon-link"></span></a>Functions:</h2>
<div class="highlight highlight-source-c++"><pre>
<span class="pl-en">Pcre2Regex</span>(){pat_str=<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>;modifier=<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>;mylocale=DEFAULT_LOCALE;}
<span class="pl-en">Pcre2Regex</span>(<span class="pl-k">const</span> std::string& re,<span class="pl-k">const</span> std::string& mod=<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>,<span class="pl-k">const</span> std::string& loc=DEFAULT_LOCALE)
{pat_str=re;modifier=mod;mylocale=loc;}
<span class="pl-en">~Pcre2Regex</span>(){<span class="pl-c1">free</span>();}
<span class="pl-k">void</span> <span class="pl-en">parseReplacementOpts</span>(<span class="pl-k">const</span> std::string& mod);
<span class="pl-k">void</span> <span class="pl-en">parseCompileOpts</span>(<span class="pl-k">const</span> std::string& mod);
<span class="pl-k">void</span> <span class="pl-en">parseOpts</span>(<span class="pl-k">const</span> std::string& mod){<span class="pl-c1">parseReplacementOpts</span>(mod);<span class="pl-c1">parseCompileOpts</span>(mod);}
std::string <span class="pl-en">getModifier</span>(){<span class="pl-k">return</span> modifier;}
<span class="pl-k">void</span> <span class="pl-en">setModifier</span>(<span class="pl-k">const</span> std::string& mod){modifier=mod;}
std::string <span class="pl-en">getPattern</span>(){<span class="pl-k">return</span> pat_str;}
<span class="pl-k">void</span> <span class="pl-en">setPattern</span>(<span class="pl-k">const</span> std::string& pat){pat_str=pat;}
<span class="pl-k">void</span> <span class="pl-en">setLocale</span>(<span class="pl-k">const</span> std::string& loc){mylocale=loc;} <span class="pl-c">///Sets LC_CTYPE</span>
std::string <span class="pl-en">getLocale</span>(){<span class="pl-k">return</span> mylocale;} <span class="pl-c">///Gets LC_CTYPE</span>
pcre2_code* <span class="pl-en">getPcreCode</span>(){<span class="pl-k">return</span> code;} <span class="pl-c">///returns address to compiled regex</span>
<span class="pl-k">void</span> <span class="pl-en">free</span>(<span class="pl-k">void</span>){<span class="pl-c1">pcre2_code_free</span>(code);} <span class="pl-c">///frees memory used for the compiled regex.</span>
<span class="pl-c">///Compiles the regex.</span>
<span class="pl-c">///If pattern or modifier or both not passed, they will be defaulted to previously set value.</span>
<span class="pl-k">void</span> <span class="pl-en">compile</span>(<span class="pl-k">void</span>){<span class="pl-c1">compile</span>(pat_str,modifier,mylocale);}
<span class="pl-k">void</span> <span class="pl-en">compile</span>(<span class="pl-k">const</span> std::string& re,<span class="pl-k">const</span> std::string& mod,<span class="pl-k">const</span> std::string& loc=DEFAULT_LOCALE);
<span class="pl-k">void</span> <span class="pl-en">compile</span>(<span class="pl-k">const</span> std::string& re){<span class="pl-c1">compile</span>(re,modifier,mylocale);}
<span class="pl-c">///returns a replaced string after performing regex replace</span>
<span class="pl-c">///If modifier is not passed it will be defaulted to empty string</span>
std::string <span class="pl-en">replace</span>( std::string mains, std::string repl,<span class="pl-k">const</span> std::string& mod=<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>,PCRE2_SIZE out_size=REGEX_STRING_MAX);
std::string <span class="pl-en">replace</span>( std::string mains, std::string repl,<span class="pl-c1">size_t</span> out_size){<span class="pl-k">return</span> <span class="pl-c1">replace</span>(mains,repl,<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>,out_size);}
<span class="pl-c">///returns true for successful match, stores the match results in the specified vectors</span>
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNum& vec_num,VecNas& vec_nas,VecNtN& vec_nn,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-c">///Other variants of match function</span>
<span class="pl-c">///3-vector variants</span>
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNum& vec_num,VecNtN& vec_nn,VecNas& vec_nas,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNas& vec_nas,VecNum& vec_num,VecNtN& vec_nn,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNas& vec_nas,VecNtN& vec_nn,VecNum& vec_num,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNtN& vec_nn,VecNas& vec_nas,VecNum& vec_num,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNtN& vec_nn,VecNum& vec_num,VecNas& vec_nas,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-c">///2-vector variants</span>
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNum& vec_num,VecNas& vec_nas,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNas& vec_nas,VecNum& vec_num,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNum& vec_num,VecNtN& vec_nn,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNtN& vec_nn,VecNum& vec_num,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNas& vec_nas,VecNtN& vec_nn,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNtN& vec_nn,VecNas& vec_nas,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-c">///1-vector variants</span>
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNum& vec_num,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNas& vec_nas,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-k">bool</span> <span class="pl-en">match</span>(<span class="pl-k">const</span> std::string& subject,VecNtN& vec_nn,<span class="pl-k">bool</span> find_all=<span class="pl-c1">false</span>);
<span class="pl-c">///Error handling</span>
std::string <span class="pl-en">getErrorMessage</span>(<span class="pl-k">int</span> err_num);
std::string <span class="pl-en">getErrorMessage</span>();
std::string <span class="pl-en">getWarningMessage</span>(){<span class="pl-k">return</span> current_warning_msg;}
<span class="pl-k">int</span> <span class="pl-en">getErrorNumber</span>(){<span class="pl-k">return</span> error_number;}
<span class="pl-k">int</span> <span class="pl-en">getErrorCode</span>(){<span class="pl-k">return</span> error_code;}
PCRE2_SIZE <span class="pl-en">getErrorOffset</span>(){<span class="pl-k">return</span> error_offset;}</pre></div>
<h1>
<a id="testing" class="anchor" href="#testing" aria-hidden="true"><span class="octicon octicon-link"></span></a>Testing:</h1>
<ol>
<li>
<strong>test.cpp</strong>: Contains an example code for match and replace function.</li>
<li>
<strong>test_match.cpp</strong>: Contains an example code for match function.</li>
<li>
<strong>test_replace.cpp</strong>: Contains an example code for replace function.</li>
</ol>
<h1>
<a id="screenshots-of-some-test-outputs" class="anchor" href="#screenshots-of-some-test-outputs" aria-hidden="true"><span class="octicon octicon-link"></span></a>Screenshots of some test outputs:</h1>
<h2>
<a id="test_match" class="anchor" href="#test_match" aria-hidden="true"><span class="octicon octicon-link"></span></a>test_match:</h2>
<p><img src="img/s1_1.png" alt="jpcre2 screenshot1">
<img src="img/s1_2.png" alt="jpcre2 screenshot2">
<img src="img/s1_3.png" alt="jpcre2 screenshot3">
<img src="img/s1_4.png" alt="jpcre2 screenshot4"></p>
<h2>
<a id="test_replace" class="anchor" href="#test_replace" aria-hidden="true"><span class="octicon octicon-link"></span></a>test_replace:</h2>
<p><img src="img/s2_1.png" alt="jpcre2 screenshot5"></p>
<footer class="site-footer">
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
</section>
</body>
</html>