简体   繁体   English

如何将所有大写单词更改为小写,但在Vim中排除字符串文字

[英]How change all uppercase words to lowercase, but exclude string literals in Vim

I got rather long sql script where all keyword are uppercase. 我得到了相当长的sql脚本,其中所有关键字都是大写的。 I want to change them to lowercase, but preserve exact values of string literals and my own identifers. 我想将它们更改为小写,但保留字符串文字和我自己的标识符的确切值。
For example, in this text: 例如,在本文中:

KEYWORD BEFORE 'SOME STRING LITERAL' KEYWORD AFTER
mixedCaseValue  
MY_OWN_VARAIBLE
UGLY APPERCASE KEYWORDS, other text

I want only 'KEYWORD BEFORE', 'KEYWORD AFTER' and last 'UGLY UPPERCASE KEYWORDS' to be lowercase and all other left intact. 我只想要'KEYWORD BEFORE','KEYWORD AFTER'和最后'UGLY UPPERCASE KEYWORDS'是小写的,而其他所有的都保持不变。
If I use something like this :%s/\\<\\u\\+\\>/\\L&/g , text inside quotes on the first line is also affected. 如果我使用这样的东西:%s/\\<\\u\\+\\>/\\L&/g ,第一行引号内的文字也会受到影响。

Do you have any ideas? 你有什么想法?

One way: 单程:

:%v/'/s/\(^\|\s\)\@<=\u\+\(\s\|,\)\@=/\L&/g

Explanation: 说明:

%                      # Range: All file.
v/pattern/command      # Apply command to all lines that doesn't match pattern
'                      # The pattern, so apply substitution to lines that doesn't have it.
s/string/replacement/  # Replacement command.
\(^\|\s\)\@<=          # Zero-width preceding match: Beginning of line or a space.
\u\+                   # One or more alphabetic uppercase letters.
\(\s\|,\)\@=           # Zero-width positive match: Space or comma.
\L&                    # Lowercase the string matched
/g                     # Apply globally: Many times for each line.

Result: 结果:

'SOME STRING LITERAL'  
mixedCaseValue  
MY_OWN_VARAIBLE
ugly appercase keywords, other text

假设字符串文字不跨越多行,并且在字符串文字中没有用于转义单引号的语法,我将使用以下替换命令。

:%s/\%(^\%([^']*'[^']*'\)*\)\@<=[^']\+/\=substitute(submatch(0),'\<\u\+\>','\L&','g')/g

My inner vim-loving soul cringes to write these, but... 我内心充满爱的心灵诅咒写下这些,但......

If this is something you don't have to do frequently, you might just brute-force it by appending the c flag onto your substitution command to prompt for confirmation of each change; 如果这是您不必经常做的事情,您可以通过在替换命令上附加c标志来强制它,以提示确认每个更改; you should be able to blow through a lot of script quickly, if you can put up with the tedium. 你应该能够快速完成大量的脚本,如果你能忍受沉闷的话。 It might be faster this way (in the short term) than by spending time crafting a good substitution command. 这种方式(在短期内)可能比花时间制定一个好的替代命令更快。

Alternatively, if there are only a handful of string literals that need to not be touched, change those to some other string so the global substitution doesn't change them, do the global substitution, and then change them back. 或者,如果只有少数字符串文字需要不被触及,请将其更改为其他字符串,以便全局替换不会更改它们,执行全局替换,然后将其更改回来。 Also gross but effective. 也很粗但有效。

Ugh, I feel dirty. 呃,我觉得很脏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM