使用Batch,我正在寻找一种方法来(1)搜索正则表达式模式和(2)在该模式中存储变量......所以我可以在进行搜索和替换时使用这些变量。
我一直在使用由@dbenham(original REPL.BAT post和earliest StackOverflow post)创建的REPL.BAT。以下是该场景的一个示例。
我搜索文档以查找以下代码:
driver.find_element_by_id("username").send_keys("rwbyrd")
driver.find_element_by_id("password").send_keys("password")
并将其替换为......
login("rwbyrd","password")
使用以下批处理代码:
type %filename% | repl "\sdriver\.find_element_by_id\(\x22username\x22\)\.send_keys\(\x22rwbyrd\x22\)\s*driver\.find_element_by_id\(\x22password\x22\)\.send_keys\(\x22password\x22\)" "login(\x22rwbyrd\x22,\x22password\x22)" MX >%filename%.new
注意:\ x22 =双引号的十六进制
我正在寻找的是一种存储[用户名]' rwbyrd'和[密码]'密码'来自代码I的值搜索&在进行替换时使用这些值。我想在REPL.BAT命令中找到一种方法来实现这一点,但我会采取我能得到的:)。有谁知道如何实现这一目标?提前谢谢!
答案 0 :(得分:2)
使用正则表达式时,必须注意\s
元字符匹配"任何空白字符。这包括空格,制表符和换页符。",但不是CR + LF对的行尾字符,因此您必须将它们包含在正则表达式中。
存在另一个类似于dbenham的REPL.BAT的程序;它被称为FindRepl.bat,您可以从this site下载它。在FindRepl替换字符串中,您可以包含$ 1,$ 2等,以获取匹配的"子表达式的值#34;括在括号中。例如,此输入文件:
Any previous line
driver.find_element_by_id("username").send_keys("rwbyrd")
driver.find_element_by_id("password").send_keys("password")
any posterior line
...通过以下行与FindRepl.bat一起处理:
type filename.txt | findrepl /Q:' "\sdriver\.find_element_by_id\('username'\)\.send_keys\('(.*)'\)\r\n\s*driver\.find_element_by_id\('password'\)\.send_keys\('(.*)'\)" "login('$1','$2')"
...产生这个输出:
Any previous line
login("rwbyrd","password")
any posterior line
您可以测试相同的正则表达式是否在REPL.BAT中生成相同的输出。
PS - 我强烈建议您查看FindRepl /?
建议的正则表达式文档。
编辑:我借用了dbenham的答案评论中所述的想法,并使用它通过我的FindRepl.bat中的替换文本中放置的JScript表达式来实现匹配的子字符串的处理程序;这样做的唯一要求是包含new / J(JScript表达式)开关并正确写入替换表达式。
程序中的修改相对简单,只需要5行新行,其中包括2行新文档;我使用this site的示例作为基础来完成修改。下面的列表是通过fc /N FindRepl.bat "FindRepl Modified.bat"
命令比较FindRepl.bat程序的原始版本和新版本的结果:
Comparing files FindRepl.bat and FINDREPL MODIFIED.BAT
***** FindRepl.bat
28: FINDREPL [/I] [/V] [/N] rSearch [/E:rEndBlk] [/O:s:e] [/B:rBlock] [/$:s1...]
29: [[/R] [/A] sReplace] [/Q:c] [/S:sSource]
30:
***** FINDREPL MODIFIED.BAT
28: FINDREPL [/I] [/V] [/N] rSearch [/E:rEndBlk] [/O:s:e] [/B:rBlock] [/$:s1...]
29: [[/R] [{/J|/A}] sReplace] [/Q:c] [/S:sSource]
30:
*****
***** FindRepl.bat
39: /R Prints only replaced lines, instead of all file lines.
40: /A Specifies that sReplace has alternative values matching rSearch.
***** FINDREPL MODIFIED.BAT
39: /R Prints only replaced lines, instead of all file lines.
40: /J Specifies that sReplace is a JScript expression, not a string.
41: /A Specifies that sReplace has alternative values matching rSearch.
*****
***** FindRepl.bat
48: The replacement string may use $ to retrieve saved submatched substrings. See:
49: http://msdn.microsoft.com/en-us/library/t0kbytzc(v=vs.84).aspx
50: Use /A switch to insert several values separated by pipe in rSearch/sReplace.
***** FINDREPL MODIFIED.BAT
49: The replacement string may use $ to retrieve saved submatched substrings. See:
50: http://msdn.microsoft.com/en-us/library/t0kbytzc(v=vs.84).aspx If /J switch
51: is given, the replacement text is an expression that must use submatched $.
52: Use /A switch to insert several values separated by pipe in rSearch/sReplace.
*****
***** FindRepl.bat
89: // FINDREPL [/I] [/V] [/N] rSearch [/E:rEndBlk] [/O:s:e] [/B:rBlock] [/$:s1...]
90: // [[/R] [/A] sReplace] [/Q:c] [/S:source]
91:
***** FINDREPL MODIFIED.BAT
91: // FINDREPL [/I] [/V] [/N] rSearch [/E:rEndBlk] [/O:s:e] [/B:rBlock] [/$:s1...]
92: // [[/R] [{/J|/A}] sReplace] [/Q:c] [/S:source]
93:
*****
***** FindRepl.bat
105: justReplaced = options.Exists("R"),
106: replace = undefined,
***** FINDREPL MODIFIED.BAT
107: justReplaced = options.Exists("R"),
108: JSexpr = false,
109: replace = undefined,
*****
***** FindRepl.bat
159: if ( quote != undefined ) replace = replace.replace(eval("/"+quote+"/g"),'"');
160: if ( options.Exists("A") ) { // Enable alternation replacements from "Se|ar|ch" to "Re|pla|ce"
161: var Asearch = search.split("|"),
***** FINDREPL MODIFIED.BAT
162: if ( quote != undefined ) replace = replace.replace(eval("/"+quote+"/g"),'"');
163: if ( options.Exists("J") ) { // Replacement text is a JScript expression with the return value of function($0,$1,$2)
164: JSexpr = true;
165: } else if ( options.Exists("A") ) { // Enable alternation replacements from "Se|ar|ch" to "Re|pla|ce"
166: var Asearch = search.split("|"),
*****
***** FindRepl.bat
335: if ( match(fileContents[lineNumber-1],search) ) {
336: WScript.Stdout.WriteLine(fileContents[lineNumber-1].replace(search,replace));
337: result++;
***** FINDREPL MODIFIED.BAT
340: if ( match(fileContents[lineNumber-1],search) ) {
341: WScript.Stdout.WriteLine(fileContents[lineNumber-1].replace(search,JSexpr?function($0,$1,$2){return(eval(replace))}:replace));
342: result++;
*****
***** FindRepl.bat
345: } else { // Replace on entire file
346: WScript.Stdout.Write(fileContents.replace(search,replace));
347: }
***** FINDREPL MODIFIED.BAT
350: } else { // Replace on entire file
351: WScript.Stdout.Write(fileContents.replace(search,JSexpr?function($0,$1,$2){return(eval(replace))}:replace));
352: }
*****
上一个列表应该足以获得FindRepl.bat的修改版本。这样,为了将第一个匹配的子表达式替换为大写字母,只需使用:
type filename | findrepl "(.*)" /J "$1.toUpperCase()"
此功能非常强大,因为替换文本可能是任何有效的JScript表达式,可以使用任何字符处理方法。例如:
type filename | findrepl "before (.*) after" /J "'before'+$1.substr(0,4).toUpperCase()+'after'"
您甚至可以通过逗号JScript运算符引入更复杂的JScript替换表达式,其中包含多个赋值(对辅助变量)。
答案 1 :(得分:1)
如果您还没有这样做,我强烈建议您从命令提示符执行以下命令:
获取特定于REPL.BAT的帮助:
repl /?
获取有关REPL.BAT使用的JScript正则表达式的帮助(在Web浏览器中打开MicroSoft文档)
repl /?regex
获取有关替换子匹配功能的帮助 - "变量"您正在寻找(在您的网络浏览器中打开MicroSoft文档)
repl /?replace
我在搜索正则表达式中用\s
(单词边界)替换了前导\b
。我还使用未转义的括号来捕获用户名和密码值,以便我可以在替换字符串中使用它们。 .*?
匹配括号文字内的内容(非贪婪匹配)。一个化妆品更改是使用\q
而不是\x22
。
type %filename% | repl "\bdriver\.find_element_by_id\(\qusername\q\)\.send_keys\((.*?)\)\s*driver\.find_element_by_id\(\qpassword\q\)\.send_keys\((.*?)\)" "login($1,$2)" MX >%filename%.new
<强>更新强>
根据OP的评论和Aacini的回答,我更新了REPL.BAT以接受J选项,将替换值指定为JScript表达式。
以下示例将用户名转换为大写:
type %filename% | repl "\bdriver\.find_element_by_id\(\qusername\q\)\.send_keys\((.*?)\)\s*driver\.find_element_by_id\(\qpassword\q\)\.send_keys\((.*?)\)" "'login('+$[1].toUpperCase()+','+$[2]+')'" MXJ >%filename%.new
有关详细信息和示例,请参阅http://www.dostips.com/forum/viewtopic.php?p=37855#p37855。