简体   繁体   English

如何将 append 文本发送到包含 Perl 中的替换的行?

[英]How do I append text to the line containing a substitution in Perl?

My goal is to replace all named constants in a *.bas file with their corresponding values, then append a comment to the line with the value-constant pair for future reference.我的目标是用它们对应的值替换*.bas文件中的所有命名常量,然后 append 对带有值-常量对的行的注释以供将来参考。

For example, I want to change this line:例如,我想更改这一行:

Print #lngFile, rst.GetString(adClipString, -1, ",", vbNullString);

To this:对此:

Print #lngFile, rst.GetString(2, -1, ",", vbNullStrings); '2=adClipString

Where the ADODB constant adClipString is replaced with its long value 2 , and a comment is appended to the line.其中 ADODB 常量adClipString被其长值2替换,并且注释被附加到该行。

The closest I've gotten is the following:我得到的最接近的是以下内容:

perl -pi -e 's/adClipString(.+\n)/2$1\x272=adClipString\n/' -- somefile.bas

...but I can't figure out how to exclude the \n from the capturing group without also overwriting every line in the file. ...但我不知道如何在不覆盖文件中每一行的情况下从捕获组中排除\n As written, the comment is placed on a new line (which is not what I want).如所写,注释被放在一个新行上(这不是我想要的)。 I'm sure the answer is right in front of me.我确信答案就在我面前。

I'm new to perl, having only run it on the command line.我是 perl 的新手,只在命令行上运行它。 I'm sure there is a better [read: working] way to approach this.我确信有更好的[阅读:工作]方法来解决这个问题。

. doesn't match newlines, and perl -p processes one line at a time, so the string to replace never contains more than one line, and you don't need to match the newline character at all.不匹配换行符,并且perl -p一次处理一行,因此要替换的字符串永远不会包含超过一行,并且您根本不需要匹配换行符。

perl -pi -e 's/\badClipString\b(.*)/2$1\x272=adClipString/' -- somefile.bas

I changed .+ to .* because you didn't give any indication that adClipString shouldn't be matched at the end of a line.我将.+更改为.*因为您没有给出任何指示adClipString不应在行尾匹配。 I also surrounded the word to replace with \b so that things like thisIsABadClipStringOtherVariable won't get replaced.我还用\b包围了要替换的单词,这样像thisIsABadClipStringOtherVariable这样的东西就不会被替换。

The added complication is that you have a file with Windows line endings: CR+LF.增加的复杂性是您有一个带有 Windows 行结尾的文件:CR+LF。 . doesn't match LF (line feed, the Unix/POSIX/basically-everyone-but-Windows-nowadays newline character) but it does match CR (carriage return).不匹配 LF(换行符,Unix/POSIX/basically-everyone-but-Windows-nowadays 换行符),但它匹配 CR(回车)。 So this replacement puts a CR in the middle of the line (just before the comment start), which may confuse Windows programs.所以这个替换将 CR 放在了行的中间(就在注释开始之前),这可能会混淆 Windows 程序。 One way to fix this is to exclude the CR from the “rest of line” group.解决此问题的一种方法是将 CR 从“其余行”组中排除。

perl -pi -e 's/\badClipString\b([^\r\n]*)/2$1\x272=adClipString/' -- somefile.bas

Another way to do this transformation would be to treat the string replacement and adding a comment as separate operations.进行此转换的另一种方法是将字符串替换和添加注释视为单独的操作。 An s command is considered true only if it makes a replacement.一个s命令只有在进行替换时才被认为是真的。

perl -pi -e 's/\badClipString\b/2/ and s/\r?$/\x272=adClipString$&/' -- somefile.bas

Or, in a less one-liner-y but more readable way:或者,以一种不那么单行但更易读的方式:

perl -pi -e 'if (s/\badClipString\b/2/) { s/\r?$/\x272=adClipString$&/ }' -- somefile.bas

The regex \r?$ matches at the end of a line, with an optional CR.正则表达式\r?$匹配行尾,带有可选的 CR。 The substitution puts additional text at the end of a line, with $& (which stands for the whole string matched by the regex) at the end to preserve the optional CR.替换将附加文本放在行尾,并在末尾添加$& (代表与正则表达式匹配的整个字符串)以保留可选的 CR。

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

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