在C/C++中定义新的类似POSIX的字符类名

  • 本文关键字:字符 POSIX C++ 定义 c++ c regex
  • 更新时间 :
  • 英文 :


我目前正在c++中开发一个项目,将regex用作HTTP FRC规则。在RFC 1945第2.2章-基本规则中,有以下规则:

CHAR           = <any US-ASCII character (octets 0 - 127)>
CTL            = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>
CRLF           = CR LF
LWS            = [CRLF] 1*( SP | HT )
word           = token | quoted-string
token          = 1*<any CHAR except CTLs or tspecials>
tspecials      = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
quoted-string  = ( <"> *(qdtext) <"> )
qdtext         = <any CHAR except <"> and CTLs, but including LWS>

我感兴趣的是像[:digit:]这样的字符类的使用,或者至少是回收regex。伪代码会变成这样(已经转义,regex已经是字符串形式(:

CHAR           = "\x00-\x7F"
CTL            = "\x00-\x19\x7F"
CR             = "\r"
LF             = "\n"
SP             = "\x20"
HT             = "\t"
//here I start "recycling" old regexes
CRLF           = "[:CR:][:LF:]"
LWS            = "[:CRLF:]* ( [:SP:] | [:HT:] )+"
//here a declaration might happen before using the token or quoted_string class
word           = "[:token:] | [:quoted_string:]"
token          = "( (?= [[:CHAR:]] ) [^[:tspecial:][:CTL:]] )+"
tspecials      = "()<>@,;:\\\"/\[\]?={}[:SP:][:HT:]"
quoted_string  = " ( \" ([:qdtext:])* \" ) "
//Little trick to allow LWS but not CTLs: https://stackoverflow.com/a/18017758/9373031
qdtext         = "(?=[[:CHAR:]]) ( [:LWS:] | [^\"[:CTL:]] )"

到目前为止,我尝试的是将它们存储为字符串,然后用+将它们链接在一起,但看起来很难看,也不是很优化。当然,我可以重复一些正则表达式,但我越走越远,它就开始变成一个巨大的怪物。

我试着在谷歌上搜索了一段时间,但也没有发现任何关于添加自定义POSIX类的信息,也没有发现关于回收(和优化?(regexs的信息。

我需要做的是优化和美化正则表达式的原始字符串,这样它们就可以被解析为一个新的类POSIX,或者以其他方式(C/C++中的代码(:

std::regex CR ("\r");
std::regex LF ("\r");
std::regex CRLF ("[:CR:] [:LF:]");

选项1:
[:CR:] [:LF:]将扩展为\r \n,编译时将变为:std::regex CRLF ("\r \n");

选项2:
[:CR:] [:LF:]将是";展开的";作为";两个功能";以在运行时优化regex。

到目前为止,我发现std::ctype_base具有用于std::regex_traits<CharT>::lookup_classname函数中类名的静态方法,该方法应用于查找已定义的类名:是否可以扩展所使用的掩码?

您需要一种元语言和一些编译器。这不是的任务,只是C++预处理器或/和编译器的常量折叠或其他编译阶段功能。

使用元语言,您将描述您的扩展RE变体。然后,您的编译器将解析该变体,并为主项目生成一些输入-要么只是一组用作传统RE输入的字符串,要么是更智能、更复杂的字符串。

用于您任务的工具确实存在:http://www.nongnu.org/bnf/、flex/bison等。它们不仅允许您只生成一组RE字符串,还可以为您的元语言创建整个解析器(您已经要求进行优化(——如果您的项目允许这样的概念的话。

或者,您可以从头开始编写自己的解析器。

最新更新