从代码行中删除变量名(JS 中的伪代码)
Posted
技术标签:
【中文标题】从代码行中删除变量名(JS 中的伪代码)【英文标题】:Removing Variable Names From Line Of Code (Psuedocode in JS) 【发布时间】:2021-06-02 17:01:39 【问题描述】:我用一些正则表达式编写了一个脚本来进行元编程。但是,我发现我无法使用一些较新的正则表达式功能,例如负后视,并且由于我在该机器上的限制,我无法安装 Perl 或其他可能的解决方案来获得访问权限。因此,我正在寻找一个 bash 脚本来完成从文本字符串中删除某些单词,而该字符串恰好是从 C++ 文件中提取的。
这是我得到的文本输入示例,它看起来像 C++ 函数签名:
int test(int aaaa, Vector<int, bool*> bbbb, Bar**cccc, Foo, Transform&eeee)
我想删除代表变量名称的字符串。在此示例中,即:aaaa
、bbbb
、cccc
和 eeee
。
输出应该是这样的,就好像它只是一个前向声明:
int test(int, Vector<int, bool*>, Bar**, Foo, Transform&)
我的解决方案是做一些事情,但我不确定是否有更好的 bash 解决方案来满足我的需求-结束。
我用 JS 编写了这个脚本来帮助完成我想要的。希望对你有帮助!
var text = 'int test(int aaaa, Vector<int, bool*> bbbb, Bar**cccc, Foo, Transform&eeee)'
var index = 0
var insideparentheses = false
var deleting = false
var readdatatype = false
var insidebrackets = 0
while(index < text.length)
if(text[index] == '(')
insideparentheses = true
deleting = false
readdatatype = false
readletter = false
if(text[index] == ')')
insideparentheses = false
deleting = false
readdatatype = false
readletter = false
if(text[index] == '<')
insidebrackets++
if(text[index] == '>')
insidebrackets--
readletter = true
if(insideparentheses && insidebrackets == 0)
if(text[index].match(/[a-zA-Z]/gi) != null)
readletter = true
if(text[index] == '*')
readdatatype = true
if(text[index] == '&')
readdatatype = true
if(text[index] == ' ')
if(readletter)
readdatatype = true
else
readdatatype = false
if(text[index] == ',')
deleting = false
readdatatype = false
readletter = false
if(text[index].match(/[_ a-zA-Z]/gi) != null)
if(readdatatype)
deleting = true
else
deleting = false
if(deleting)
text = text.substring(0, index) + text.substring(index + 1)
else
index++
continue
else
index++
continue
console.log(text)
编辑:变量可以命名为任何在 C++ 中有效的名称,例如 [_a-zA-Z]+
,而不仅仅是同一个字母的 4 个,重复 4 次...:P
【问题讨论】:
我确信这可以在sed
中完成,但我也确信这将是相当可怕的。是否可以接受 awk 解决方案?
嗨。我对正则表达式非常满意,sed
不适用于我的解决方案,因为我的平台上没有像lookbehind 这样的正则表达式功能。如果您想出一个不使用后向/前瞻的sed
解决方案,我可以尝试一下!此外,awk
无法安装,这是我肯定已经尝试过的。 :P
Perl 怎么样?
@tripleee,在问题中,我指定我无法在环境中安装 Perl 作为解决此问题的方法。
哦,对不起,我错过了。您可能可以做一些逻辑将整行划分为保持空间和模式空间,然后处理模式空间,然后将它们合并在一起;但这些解决方案往往是只写的,特别是如果您对sed
概念不是很熟悉。参见例如一些potong's answers 用于演示此类解决方案的外观。
【参考方案1】:
使用正则表达式而不是专门的工具来解析这些东西是 会很脆弱,因为它可能会在额外的空白处失败,例如。
不过,这里有一个使用 POSIX 的 sed
版本
ERE 正则表达式,
假设输入有效且简单。
如果您的sed
不理解\n
(GNU sed
可以)尝试
用反斜杠换行符替换它。
sed -E -e '
:S
s/^(([^<]*<[^>]*>)*[^<]*), */\1\n/
tS
s/(\n|\()([[:alpha:]_][[:alnum:]_]*)(\n|\)$)/\1\2 ident\3/g
s/([[:print:]])([ ]*[[:alpha:]_][[:alnum:]_]*)(\n|\)$)/\1\3/g
s/[ ]*\n/, /g
' -- data
地点:
第一个s
:用< >
替换最后一个(*
是贪婪的)逗号
换行符
t
:如果进行了替换,则循环返回,以使每行一个参数
第二个s
:如果参数中没有标识符,则插入一个以简化以下替换(第三个s
)
第三个s
:剥离标识符; “打印”LC_CTYPE 定义为“alnum”、“punct”和空格
4th s
:将所有行合并为一个
测试数据:
int test(int aaaa, Vector<int, bool*> bbbb, Bar**cccc, Foo, Transform&eeee)
long tst2(Vector<bool*, str*> vbs, int i, Quux<Foo, int*>, Bar*bp)
longlong tst3(long l, Foo f, Vector<int, bool*, str*> vibs, Vector<int>vi, Bar**bpp, Phoo&)
int (*ff(int))(int*, int)
int (*pfc)(const char* p1, const char* p2)
输出:
int test(int, Vector<int, bool*>, Bar**, Foo, Transform&)
long tst2(Vector<bool*, str*>, int, Quux<Foo, int*>, Bar*)
longlong tst3(long, Foo, Vector<int, bool*, str*>, Vector<int>, Bar**, Phoo&)
int (*ff(int))(int*, int)
int (*pfc)(const char*, const char*)
【讨论】:
哇!这有效,即使它没有直接回答关于转换 JS 代码的部分问题!谢谢!!好激动!! @crait:嗯,您的帖子包含一个sed
标签,我对此进行了回复。如果您更喜欢其他工具,也许我的正则表达式中的想法会很有用。【参考方案2】:
这可能对你有用(GNU sed):
sed 's/ \?\([abcde]\)\1\1\1//g' file
在整个文件中全局删除一个可选空格,后跟aaaa
、bbbb
、cccc
、dddd
或eeee
。
编辑:
sed -E 's/\((.*)\)/(\n\1\n)/;T;h;s/.*\n(.*)\n.*/\1/;y/,/\n/
s#.*#echo "&"|sed -E "s/^ +//;s/( |(\\*\\*|\\\&))\\S+$/\\2/"#e
s/\n/, /g;H;g;s/\n.*\n(.*)\n(.*)/\2\1/' file
将线分成三部分。
在中间部分运行单独的 sed 调用。
将零件重新组合在一起。
这可能无法满足所有可能性(OP 将需要改进上述解决方案),但应该是一个开始。
注意最好利用原始语言的自省来解决这样的问题。
【讨论】:
这不是答案。变量名称为aaaaa
、bbbbb
等都是示例,我认为我的问题很清楚。变量可以命名为任何字母数字,就像在 C++ 中一样。如果数据类型使用该模式,这也会失败,例如void whatever(aaaaa foo, int bar)
。以上是关于从代码行中删除变量名(JS 中的伪代码)的主要内容,如果未能解决你的问题,请参考以下文章