首页
搜索 搜索
当前位置:商业资讯 > 正文

正则表达式 以及 北太天元的regex插件对正则字符串的支持

2023-08-11 19:29:15 哔哩哔哩


(相关资料图)

正则表达式,也称为 regex 或 RegExp,是一个字符串,用于描述或匹配一系列具有相似模式的字符串。它是编程语言中的一种工具,可以帮助我们搜索、替换、删除或处理文本。正则表达式由一系列字符组成,这些字符可以是普通字符(如 a-z,A-Z,0-9),也可以是特殊字符(如 .,[,$ 等)。这些特殊字符被称为元字符,它们具有特殊的含义,可以用来表示特定的模式。几乎所有的编程语言都支持正则表达式。C++从C++11开始直接支持正则表达式。除了编程语言之外,大多数文本处理程序(如vim)都使用正则表达式。 在这个小短文中,我们将探讨正则表达式的一般细节以及C++编程方面的细节。 从C++11开始,C++通过<regex>标头的标准库提供regex支持。C+11使用ECMAScript语法作为regex的默认语法。ECMAScript很简单,但它提供了强大的regex功能。为了把C++11的正则表达式引入到北太天元,我写了一个regex插件。在北太天元中使用正则表达式, 先加载 regex 插件.  可以通过在命令行窗口输入>> load_plugin("regex")来加载regex插件。我们先看看在正则表达式中指定范围和指定重复的一些模式(pattern).范围指定例如,我们可以指定从a到z的小写字母范围,如下所示:[a-z]   这将恰好匹配一个小写字符。[A-Za-z0-9]上面的表达式指定包含一个大写字符、一个小写字符和一个从0到9的数字的范围。这将匹配一个大写字母或者一个小写字母或者0-9之间的一个数字。 上述表达式中的方括号[]具有特殊含义,即它们用于指定范围。如果要在表达式中包含一个方括号,则需要对其进行转义。 因此,下面的表达式,[\[0-9]上面的表达式表示一个左方括号和一个范围为0到9的数字作为正则表达式。这将匹配一个左方括号或者0到9中的一个数字。但请注意,当我们用C++编程时,我们需要使用C++特定的转义序列,如下所示:[\\[0-9]也就是说为了在C++中输入 \[ 需要输入 \\[, 在北太天元总也是如此,我们用北太天元举例: Input [12] >> str = "AZ12["str =  1x1 string    "AZ12["Input [13] >> [找到的字符串,前缀,后缀] = regex_search(str, "[\[]")输入字符串分析失败,分析器已重置。错误(文件 stdin, 行1, 列37): 单引号字符矩阵模式下此输入无效上面的解析报了错,需要修改成这样Input [14] >> [找到的字符串,前缀,后缀] = regex_search(str, "[\\[]")找到的字符串 =  1x1 string    "["另外,我们再强调一下 [\[0-9]] 只会配一个字符,我们用北太天元来执行Input [15] >> [找到的字符串,前缀,后缀] = regex_search(str, "[\\[0-9]")找到的字符串 =  1x1 string    "1"这里的str = "AZ12[", 用 [\[0-9] 只匹配了第一个属于这个范围的字符 1, 后main 2[ 都成了后缀. 再看下面的例子,"AZ12[" 要查找[A-Z\[0-9]]时,就匹配了第一个找到的在此范围的字符A. Input [16] >> [找到的字符串,前缀,后缀] = regex_search(str, "[A-Z\\[0-9]")找到的字符串 =  1x1 string    "A"

重复pattern我们在上面指定的范围示例只匹配一个字符或文字。如果我们想匹配多个字符,我们通常会在指定模式的同时指定“表达式修饰符”,从而使其成为重复模式。表达式修饰符可以是“+”,表示匹配模式的出现一次或多次,也可以是“*”,表示将模式的出现匹配零次或多次。例如以下表达式,[a-z]+匹配a、aaa、abcd、softwaretestinghelp等字符串。请注意,它永远不会匹配空白字符串。北太天元的命令[a-z]*将匹配一个空白字符串或以上任何字符串。Input [20] >> [找到的字符串,~,~] = regex_search("az123", "[A-Z]+")找到的字符串 =  0x0 empty stringInput [21] >> [找到的字符串,~,~] = regex_search("az123", "[A-Z]*")找到的字符串 =  1x1 string    ""我们可以看到[A-Z]+ 要求至少要有一个大写字符,因此找到的字符串 = 0x0 empty string意味着没有找到, 而 [A-Z]* 表示0个或者以上的大写字符,因此找到的字符串是1x1 string 只不过这个string 是 "".如果确实存在大写字符,[A-Z]* 和 [A-Z]+ 返回的结果是一样的Input [24] >> [找到的字符串,~,~] = regex_search("AZ123", "[A-Z]*")找到的字符串 =  1x1 string    "AZ"Input [25] >> [找到的字符串,~,~] = regex_search("AZ123", "[A-Z]+")找到的字符串 =  1x1 string    "AZ"如果要指定一组字符匹配一次或多次,则可以使用括号,如下所示:(Xyz)+上述表达式将匹配Xyz、XyzXyz和XyzXyzXyz等。例如在北太天元上Input [39] >> [找到的字符串,q,h] = regex_search("abc12XyzXyzXyz124", "(Xyz)+")找到的字符串 =  1x2 string  列 1    "XyzXyzXyz"  列 2    "Xyz"q =  1x5 char    'abc12'h =  1x3 char    '124'这个感觉插件似乎有点问题,找到的字符串应该还是1x1 string 才对,现在多了1列。 正则表达式一个稍微有点使用价值的例子考虑一个与微软DOS文件名匹配的正则表达式,如下所示。>>regex_filename="[a-zA-Z_][a-zA-Z_0-9]*\\.[a-zA-Z0-9]+";上述正则表达式可以解释如下:匹配字母(先小写后大写)或下划线。然后匹配零个或多个字符,每个字符可以是字母、下划线或数字。然后匹配一个文字点(.)。在点之后,匹配一个或多个字符,其中每个字符都可以是表示文件扩展名的字母或数字。Input [42] >> [找到的字符串,q,h] = regex_search("", regex_filename)找到的字符串 =  0x0 empty string上面的文件名不是用字母或者下划线开头的,因此是非法的,上面的regex_search返回找到的字符串是 0x0 empty string 我们可以用北太天元的 isempty 命令来判别这一点,从而知道这是一个非法的文件名 。Input [43] >> isempty(找到的字符串)ans =  1x1 logical   1Input [44] >> [找到的字符串,q,h] = regex_search("_", regex_filename)找到的字符串 =  1x1 string    "_"这个说明"_" 是一个合法的文件名. regex_match 的用法可以用北太天元的 help regex_match 获得Input [45] >> help regex_match正则表达式匹配语法 smatch = regex_match(str, pattern)例:Input [29] >>    str = "CN2018_BEIJING";Input [30] >> patstr = "CN\\d*_BEIJING";Input [31] >> s = regex_match(str, patstr)s =  1x1 string    "CN2018_BEIJING"Input [32] >> patstr = "CN(\\d*)_BEIJING";Input [33] >> s = regex_match(str, patstr)s =  1x2 string    "CN2018_BEIJING"    "2018"Input [34] >> patstr = "CN(\\d*)_[A-Z]*";Input [35] >> s = regex_match(str, patstr)s =  1x2 string    "CN2018_BEIJING"    "2018"Input [36] >> patstr = "CN(\\d*)_([A-Z]*)";Input [37] >> s = regex_match(str, patstr)s =  1x3 string    "CN2018_BEIJING"    "2018"    "BEIJING"Input [38] >> patstr = "(CN)(\\d*)_([A-Z]*)";Input [39] >> s = regex_match(str, patstr)s =  1x4 string    "CN2018_BEIJING"    "CN"    "2018"    "BEIJING"Input [40] >> str = "2668418"str =  1x1 string    "2668418"Input [41] >> patstr = "[1-9]\\d{4,11}" %第一位数字不能为0,后面是4-11个数字patstr =  1x1 string    "[1-9]\d{4,11}"Input [42] >> s = regex_match(str, patstr)s =  1x1 string    "2668418"Input [59] >> str = "<xml>value</xml>"str =  1x1 string    "<xml>value</xml>"Input [60] >> patstr = "<(.*)>(.*)</.*>";Input [61] >> s = regex_match(str, patstr)s =  1x3 string    "<xml>value</xml>"    "xml"    "value"还有正则表达式的替换Input [46] >> help regex_replace正则表达式替换语法 替换后的字符串 = regex_replace(str, 要被替换的子串的pattern, 用这个pattern替换)例:Input [6] >>  替换后的字符串 = regex_replace("CN2018", "\\d{4}", "")替换后的字符串 =  1x2 char    'CN'替换后的字符串 = regex_replace("CN2018", "([A-Z]{2})(\\d{4})", "$1_$2")替换后的字符串 =  1x7 char    'CN_2018'Input [18] >>  替换后的字符串 = regex_replace("我的中国CN2018", "[u4e00-u9fa5]*([A-Z]{2})(\\d{4})", "$1_$2")替换后的字符串 =  1x19 char    '我的中国CN_2018'Input [19] >>  替换后的字符串 = regex_replace("我的中国CN2018", "([u4e00-u9fa5]*)([A-Z]{2})(\\d{4})", "$1_$2")替换后的字符串 =  1x15 char    '我的中国_CN'Input [20] >>  替换后的字符串 = regex_replace("CN2018", "([u4e00-u9fa5]*)([A-Z]{2})(\\d{4})", "$1_$2")替换后的字符串 =  1x3 char    '_CN'Input [21] >>  替换后的字符串 = regex_replace("CN2018", "([u4e00-u9fa5]+)([A-Z]{2})(\\d{4})", "$1_$2")替换后的字符串 =  1x6 char    'CN2018'下面列出一些基本的正则表达式元字符(metacharacter):. :匹配任何字符(除了换行符)。[...] :这里的...换成具体的字符,表示可以匹配的单个字符。例如,[am] 将匹配 "a" 或 "m"。[^...] :这里的...换成具体的字符, 表示不匹配此字符集中的任何字符。         例如,[^am] 将匹配除了 "a" 和 "m" 之外的任何字符。[^] :表示可以匹配除了换行符之外的任何字符。\d :匹配任何十进制数字(相当于 [0-9])。\D :匹配任何非数字字符(相当于 [^0-9])。\s :匹配任何空白字符(相当于 [ \t\n\r\f\v]), 这里\t表示tab,\n表示换行符,\r表示回车。\S :匹配任何非空白字符(相当于 [^ \t\n\r\f\v])。\w :匹配任何字母数字字符(相当于 [a-zA-Z0-9_])。\W :匹配任何非字母数字字符(相当于 [^a-zA-Z0-9_])。此外,正则表达式还支持一些修饰符,例如:? :表示前面的元素是可选的,可以出现零次或一次。+ :表示前面的元素是必须的,可以出现一次或多次。{n} :表示前面的元素必须出现 n 次。{n,} :表示前面的元素可以出现 n 次或更多次。{n,m} :表示前面的元素可以出现 n 到 m 次。这些只是正则表达式的基础知识,实际上正则表达式的能力远不止这些。例如,它还可以用来处理更复杂的模式,如捕获组、后向引用、条件等。