考虑一个与我的previous question稍有不同的玩具示例:
. local string my first name is Pearly,, and my surname is Spencer
. tokenize "`string'", parse(",,")
. display "`1'"
my first name is Pearly
. display "`2'"
,
. display "`3'"
,
. display "`4'"
and my surname is Spencer
我有两个问题:
在这种情况下,tokenize
是否按预期工作?我以为本地宏
2
应该是,,
而不是,
,而本地宏3
包含字符串的其余部分(本地宏4
为空)。
是否有一种方法可以强制tokenize
遵循双逗号作为语法分析
字符?
答案 0 :(得分:1)
tokenize
以及gettoken
也一样,据我所知,它们不会接受 重复 个字符,例如{{ 1}}作为 复合 解析字符。 ,,
作为解析字符的规范不是非法的,只是被理解为,,
和,
是可接受的解析字符。实际上,重复操作被忽略,就像在“我的名字叫珍珠”之后添加“我的名字叫珍珠”不会在对话中添加信息一样。
要备份:知道没有其他指令(例如,,
命令可能会给出的信息),Stata会根据空格来解析字符串,除了双引号(或复合双引号)比空格更难绑定分离。
syntax
(也包括tokenize
)将接受多个解析字符 pchars ,而gettoken
的帮助给出了一个空格和{{1 }} 标志。 (根据我的经验,当命令的语法与tokenize
完全不一样时,想使用空格和逗号+
更为常见。)
空格和其他解析字符之间的区别在于,空格被丢弃,而其他解析字符不被丢弃。这样做的理由是,这些字符通常具有您可能想表达的含义。因此,在设置命令选项的语法时,您可能需要允许类似,
varname [syntax
suboptions ] myoption(
之类的内容
因此,对于以后的代码,是否存在逗号和其他内容很重要。
使用复合字符,因此您正在寻找说,
作为分隔符,我认为您需要使用)
或等效符号来循环。在实践中,可能更容易的解决方法是先用一些中性的单个字符替换您的复合字符,然后应用,,
。那可能需要依靠知道该中立性格不应该出现。因此,我经常使用substr()
作为字符占位符,因为我知道它不会作为变量名或标量名的一部分出现,也不属于函数名或运算符的一部分。
对于它的价值,我注意到在开始写tokenize
时,我允许使用复合字符作为分隔符。我记得,触发此事件的是Statalist上的一个问题,该问题涉及@
(相对于)上有多个变体的法律案件数据,以表明哪一方是哪一方。此示例可以保留到官方命令的帮助中。
在什么是“严重”错误上,很大程度上取决于判断。我认为程序员会在尝试使用split
的情况下发现复合字符在您这样的情况下无法正常工作。