📄 regexmodule.c
字号:
(getattrfunc)regobj_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
};
/* reference counting invariants:
pattern: borrowed
translate: borrowed
givenpat: borrowed
groupindex: transferred
*/
static PyObject *
newregexobject(PyObject *pattern, PyObject *translate, PyObject *givenpat, PyObject *groupindex)
{
regexobject *re;
char *pat;
int size;
if (!PyArg_Parse(pattern, "t#", &pat, &size))
return NULL;
if (translate != NULL && PyString_Size(translate) != 256) {
PyErr_SetString(RegexError,
"translation table must be 256 bytes");
return NULL;
}
re = PyObject_New(regexobject, &Regextype);
if (re != NULL) {
char *error;
re->re_patbuf.buffer = NULL;
re->re_patbuf.allocated = 0;
re->re_patbuf.fastmap = (unsigned char *)re->re_fastmap;
if (translate) {
re->re_patbuf.translate = (unsigned char *)PyString_AsString(translate);
if (!re->re_patbuf.translate)
goto finally;
Py_INCREF(translate);
}
else
re->re_patbuf.translate = NULL;
re->re_translate = translate;
re->re_lastok = NULL;
re->re_groupindex = groupindex;
Py_INCREF(pattern);
re->re_realpat = pattern;
Py_INCREF(givenpat);
re->re_givenpat = givenpat;
error = _Py_re_compile_pattern((unsigned char *)pat, size, &re->re_patbuf);
if (error != NULL) {
PyErr_SetString(RegexError, error);
goto finally;
}
}
return (PyObject *)re;
finally:
Py_DECREF(re);
return NULL;
}
static PyObject *
regex_compile(PyObject *self, PyObject *args)
{
PyObject *pat = NULL;
PyObject *tran = NULL;
if (!PyArg_ParseTuple(args, "S|S:compile", &pat, &tran))
return NULL;
return newregexobject(pat, tran, pat, NULL);
}
static PyObject *
symcomp(PyObject *pattern, PyObject *gdict)
{
char *opat, *oend, *o, *n, *g, *v;
int group_count = 0;
int sz;
int escaped = 0;
char name_buf[128];
PyObject *npattern;
int require_escape = re_syntax & RE_NO_BK_PARENS ? 0 : 1;
if (!(opat = PyString_AsString(pattern)))
return NULL;
if ((sz = PyString_Size(pattern)) < 0)
return NULL;
oend = opat + sz;
o = opat;
if (oend == opat) {
Py_INCREF(pattern);
return pattern;
}
if (!(npattern = PyString_FromStringAndSize((char*)NULL, sz)) ||
!(n = PyString_AsString(npattern)))
return NULL;
while (o < oend) {
if (*o == '(' && escaped == require_escape) {
char *backtrack;
escaped = 0;
++group_count;
*n++ = *o;
if (++o >= oend || *o != '<')
continue;
/* *o == '<' */
if (o+1 < oend && *(o+1) == '>')
continue;
backtrack = o;
g = name_buf;
for (++o; o < oend;) {
if (*o == '>') {
PyObject *group_name = NULL;
PyObject *group_index = NULL;
*g++ = '\0';
group_name = PyString_FromString(name_buf);
group_index = PyInt_FromLong(group_count);
if (group_name == NULL ||
group_index == NULL ||
PyDict_SetItem(gdict, group_name,
group_index) != 0)
{
Py_XDECREF(group_name);
Py_XDECREF(group_index);
Py_XDECREF(npattern);
return NULL;
}
Py_DECREF(group_name);
Py_DECREF(group_index);
++o; /* eat the '>' */
break;
}
if (!isalnum(Py_CHARMASK(*o)) && *o != '_') {
o = backtrack;
break;
}
*g++ = *o++;
}
}
else if (*o == '[' && !escaped) {
*n++ = *o;
++o; /* eat the char following '[' */
*n++ = *o;
while (o < oend && *o != ']') {
++o;
*n++ = *o;
}
if (o < oend)
++o;
}
else if (*o == '\\') {
escaped = 1;
*n++ = *o;
++o;
}
else {
escaped = 0;
*n++ = *o;
++o;
}
}
if (!(v = PyString_AsString(npattern))) {
Py_DECREF(npattern);
return NULL;
}
/* _PyString_Resize() decrements npattern on failure */
if (_PyString_Resize(&npattern, n - v) == 0)
return npattern;
else {
return NULL;
}
}
static PyObject *
regex_symcomp(PyObject *self, PyObject *args)
{
PyObject *pattern;
PyObject *tran = NULL;
PyObject *gdict = NULL;
PyObject *npattern;
PyObject *retval = NULL;
if (!PyArg_ParseTuple(args, "S|S:symcomp", &pattern, &tran))
return NULL;
gdict = PyDict_New();
if (gdict == NULL || (npattern = symcomp(pattern, gdict)) == NULL) {
Py_DECREF(gdict);
Py_DECREF(pattern);
return NULL;
}
retval = newregexobject(npattern, tran, pattern, gdict);
Py_DECREF(npattern);
return retval;
}
static PyObject *cache_pat;
static PyObject *cache_prog;
static int
update_cache(PyObject *pat)
{
PyObject *tuple = Py_BuildValue("(O)", pat);
int status = 0;
if (!tuple)
return -1;
if (pat != cache_pat) {
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = regex_compile((PyObject *)NULL, tuple);
if (cache_prog == NULL) {
status = -1;
goto finally;
}
cache_pat = pat;
Py_INCREF(cache_pat);
}
finally:
Py_DECREF(tuple);
return status;
}
static PyObject *
regex_match(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_Parse(args, "(SS)", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_match((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_search(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_Parse(args, "(SS)", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_search((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_set_syntax(PyObject *self, PyObject *args)
{
int syntax;
if (!PyArg_Parse(args, "i", &syntax))
return NULL;
syntax = re_set_syntax(syntax);
/* wipe the global pattern cache */
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = NULL;
return PyInt_FromLong((long)syntax);
}
static PyObject *
regex_get_syntax(PyObject *self, PyObject *args)
{
if (!PyArg_Parse(args, ""))
return NULL;
return PyInt_FromLong((long)re_syntax);
}
static struct PyMethodDef regex_global_methods[] = {
{"compile", regex_compile, 1},
{"symcomp", regex_symcomp, 1},
{"match", regex_match, 0},
{"search", regex_search, 0},
{"set_syntax", regex_set_syntax, 0},
{"get_syntax", regex_get_syntax, 0},
{NULL, NULL} /* sentinel */
};
DL_EXPORT(void)
initregex(void)
{
PyObject *m, *d, *v;
int i;
char *s;
/* Initialize object type */
Regextype.ob_type = &PyType_Type;
m = Py_InitModule("regex", regex_global_methods);
d = PyModule_GetDict(m);
if (PyErr_Warn(PyExc_DeprecationWarning,
"the regex module is deprecated; "
"please use the re module") < 0)
return;
/* Initialize regex.error exception */
v = RegexError = PyErr_NewException("regex.error", NULL, NULL);
if (v == NULL || PyDict_SetItemString(d, "error", v) != 0)
goto finally;
/* Initialize regex.casefold constant */
if (!(v = PyString_FromStringAndSize((char *)NULL, 256)))
goto finally;
if (!(s = PyString_AsString(v)))
goto finally;
for (i = 0; i < 256; i++) {
if (isupper(i))
s[i] = tolower(i);
else
s[i] = i;
}
if (PyDict_SetItemString(d, "casefold", v) < 0)
goto finally;
Py_DECREF(v);
if (!PyErr_Occurred())
return;
finally:
/* Nothing */ ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -