Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正则表达式-在Python3中使用正则表达式生成标记器_Python_Regex_Python 3.x - Fatal编程技术网

正则表达式-在Python3中使用正则表达式生成标记器

正则表达式-在Python3中使用正则表达式生成标记器,python,regex,python-3.x,Python,Regex,Python 3.x,作为练习,我一直在尝试为一种语言制作一个标记器。 例如,我正在尝试标记下面的代码 num vecsum(vec A) { num n; n = (5 + 2); return n; } 我一直在尝试使用这个正则表达式 re.findall("[\'\w\-]+",text) 但是我得到了如下输出:vecsum(vec 而我想这样得到:[“vecsum”,“(”,“vec”] 我想让它明白,即使没有空格,它也应该拆分“;”和“(“标记类似C语言需要更多的工作,而不仅仅是拆分空格(这是您现在正在

作为练习,我一直在尝试为一种语言制作一个标记器。 例如,我正在尝试标记下面的代码

num vecsum(vec A)
{
num n;
n = (5 + 2);
return n;
}
我一直在尝试使用这个正则表达式

re.findall("[\'\w\-]+",text)
但是我得到了如下输出:vecsum(vec

而我想这样得到:[“vecsum”,“(”,“vec”]


我想让它明白,即使没有空格,它也应该拆分“;”和“(“

标记类似C语言需要更多的工作,而不仅仅是拆分空格(这是您现在正在做的)

此类语言中至少有3种类型的标记:

  • 单字符标记,例如
    +
    =
  • 多字符标记、标识符、关键字、数字
  • 字符串;介于开始引号和匹配结束引号之间的所有内容(支持转义,并不同程度地支持可能包含换行符的特殊类型的字符串)
我在这里忽略注释,它们要么定义为从开始序列运行到行尾(
#…
/…
,等等),要么定义为从开始序列运行到结束序列,任意数量的行(
/*…/

您可以定义一个可以标记前两种类型的正则表达式,然后可能使用它的输出来处理字符串(当您获得
标记时,找到下一个
标记,前面没有
\
标记,然后将中间的所有内容(空格和all)都作为字符串)

这种标记器至少需要两组,即单字符标记和多字符标记。多字符标记是另一组选项:

r'(?:[\\(){}[\]=&|^+<>/*%;.\'"?!~-]|(?:\w+|\d+))'
如果必须将多符号运算符解析为单个标记,那么还必须将它们作为单独的模式包含在正则表达式中,例如

(
    r'(?:==|!=|>=|<=|&&|\|\||<<|>>|->|::|\+\+|--|+=|-='
    r'|\*=|/=|%=|<<=|>>=|&=|\^=|\|='
    r'|[\\(){}[\]=&|^+<>/*%;.\'"?!~-]|(?:\w+|\d+))'
)
(
r'(?:===|!=|>=|:::|\+\+\-|+=|-='
r'|\*=|/=|%=|=|&=|\^=|\|='
r'|[\(){}[\]=&| ^+/*%.\'“?!~-].[?:\w+\d+)”
)
但是现在你已经到了为每种文字和关键字定义模式的成熟标记器的一半了,你也可以开始将这个巨大的正则表达式分解成这样的组成部分


另一种选择是坚持使用超级简单的两部分标记器regex,并使用它在上下文中对标记进行决策。在字符串中有
开始
结束
位置,您可以检测到
=
前面直接有
=
,因此知道您有
=
比较运算符,而不是two分配。我以前在SQLite全文搜索查询语言的一个简单解析器中使用过它(在,如果您想查看示例。

已经是
\S
的一部分,无需单独添加。请确保在具有文字反斜杠的字符串之前使用
r
。您的意思是:
findall(r”\w+[^\w\S]+,text)
?或类似的:
r”\S+(?:\b$)“
@trincot:这仍然将符号放在一个标记中:
if(foo){bar++;baz-->
将导致
['if',(','foo','){','bar','++;'baz','-}]
;注意
++;
-}
的连接。只是试图从显然选择保持沉默的PO那里获得一些信息而已。”正如你所说,我现在有这样一个:re.findall(“\w+(?:'\w+)?”[^\w\s]”,text)这是可行的,但它不能识别像==这样的多字符标记,或者我测试了你的代码,但仍然有相同的问题tokens@mahditalebi我没有说我的方法会识别多字符运算符。你必须在单字符运算符模式之前将它们作为单独的组添加。严重的是基于gex的令牌大小调整器使用大量特定模式。
(
    r'(?:==|!=|>=|<=|&&|\|\||<<|>>|->|::|\+\+|--|+=|-='
    r'|\*=|/=|%=|<<=|>>=|&=|\^=|\|='
    r'|[\\(){}[\]=&|^+<>/*%;.\'"?!~-]|(?:\w+|\d+))'
)