标题: [其他] 【已解决】fr.exe(find - replace)的正则匹配问题 [打印本页]
作者: kidzgy 时间: 2022-11-26 14:46 标题: 【已解决】fr.exe(find - replace)的正则匹配问题
本帖最后由 kidzgy 于 2022-11-29 19:15 编辑
fr文件:http://bcn.bathome.net/tool/2.1.7.0424/fr.exe
fr文件操作说明:http://baiy.cn/utils/fr/index.htm
正则测试文件(文件名为extensions.json,全文单行内容):https://pastebin.ubuntu.com/p/QfgD7xzntJ/plain/
正则测试主要内容(源测试文件内容较多,将无关内容去除后的主要内容)- "path":"D:\\Firefox106\\Profiles\\extensions\\s3google@translator.xpi","path":"D:\\Firefox106\\browser\\features\\screenshots@mozilla.org.xpi",,"path":"D:\\Firefox106\\browser\\features\\webcompat@mozilla.org.xpi",
复制代码
正则测试语句:- \"path\"\:\".*?\\\\(browser\\\\features|Profiles\\\\extensions).*?
复制代码
要点:- (1)【D:\\Firefox106】路径不唯一,它可以是任何路径,任意文件夹名。fr的最终目的就是,不管当前路径如何,在fr.exe后,重新刷新为当前路径。比如,当前路径是【D:\\Firefox106】,但我又把Firefox106文件夹放到【C:\123】在fr.exe,那路径就该是【C:\123\Firefox106】。
- (2)在用 regex101.com 测试的时候,通过上述测试语句搜索,匹配的内容是【D:\\Firefox106\\Profiles\\extensions】或【D:\\Firefox106\\browser\\features】
复制代码
,并且将【Profiles\\extensions】或【browser\\features】设置为【组1(即\1)】。
我在regex101测试内容截图:
我的批处理命令行内容如下:- @ECHO OFF&(PUSHD "%~DP0")
- set firefox=%~DP0
- set firefox1=%firefox:\=/%
- set firefox2=%firefox:\=\\\\%
- fr.exe "extensions.json" -ric:"***:file:\/\/\/.*?\/(Profiles\/extensions|browser\/features).*?" -t:"file:///%firefox1%\1"
- fr.exe "extensions.json" -ric:"***:\"path\"\:\".*?\\\\(browser\\\\features|Profiles\\\\extensions).*?" -t:""path":"%firefox2%\1"
复制代码
发现 第一条fr.exe 这条语句是可以成功替换的,但是第二条 fr.exe 则是替换失败,本帖的内容就是讨论第二条的执行问题,不知道原因在哪里?
请问,语句应该怎么修改?或者是否必须使用fr外的第三方命令工具,如果是其他第三方工具命令行内容该如何填写?
作者: hfxiang 时间: 2022-11-27 09:28
估计使用fr.exe( find - replace )的人不很多。如用“正则表达式”处理文档,建议使用gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )或者sed( http://bcn.bathome.net/tool/4.8/sed.exe ),这2工具在网上的资料相对容易找到。如能更清晰列出处理前的文档及处理后的文档,并附修改说明,应该能有解决方案。
作者: kidzgy 时间: 2022-11-27 10:56
回复 2# hfxiang
sed似乎不支持懒惰模式。
作者: pd1 时间: 2022-11-27 11:08
关键是把上上楼说的如能给出后面的内容给出来。
不管什么语言,正则表达式都是一个东西,最多有点细微差别
补充一句,把会影响通用性的反例加进去,以防写好后再返工
作者: kidzgy 时间: 2022-11-28 09:15
或者我换种提法,以【\\browser\\features】为基准,怎么向前匹配最近的一个【path】?如图所示,红色区域是我最终想匹配的内容。
为什么我这里懒惰匹配,还能匹配到最开头的【path】?- (?<=path\"\:\").*?(\\\\browser\\\\features).*?
复制代码
- "path":"D:\\Firefox106\\Profiles\\extensions\\s3google@translator.xpi","path":"D:\\Firefox106\\browser\\features\\screenshots@mozilla.org.xpi"
复制代码
作者: hfxiang 时间: 2022-11-28 09:46
本帖最后由 hfxiang 于 2022-11-28 11:49 编辑
回复 5# kidzgy
下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )
执行- gawk "{print gensub(/^.*\"path\":\"(.+\\\\browser\\\\features).+\".*$/,\"\\1\",\"g\")}" extensions.json>con
复制代码
结果- D:\\Firefox106\\browser\\features
复制代码
作者: Batcher 时间: 2022-11-28 09:47
回复 5# kidzgy
这样可以吗- (?<=path\"\:\")[^,]+(\\\\browser\\\\features)
复制代码
作者: Batcher 时间: 2022-11-28 10:02
回复 5# kidzgy
sed试试这样- sed -r "s#\"path\".*:\x22([^\x22]+\\\\browser\\\\features).*#\1#" 1.txt > 2.txt
复制代码
作者: kidzgy 时间: 2022-11-28 10:11
回复 7# Batcher
感谢解答!这个绝了,用逗号做分割。我有个疑问,假设分割的不是逗号,而是apple这个词组或某个句子,那么这个【[^,]+】应该怎么写?
作者: terse 时间: 2022-11-28 10:27
既然是json文件,那就按json处理呢?不用正则应该可以,如有样本可以试一下
作者: kidzgy 时间: 2022-11-28 10:58
回复 10# terse
json样本
https://wwi.lanzoup.com/ifb2r0h3ap1c
作者: WHY 时间: 2022-11-28 11:04
要用到所谓的"零宽断言"才能实现,不知道 fr.exe 支不支持
在 UltraEdit 中,选替换
正则选- ^.*?("path":(?:(?!"path":).)*\\\\browser\\\\features).*$
复制代码
替换为选 \1
正则勾选 Perl
作者: WHY 时间: 2022-11-28 12:07
本帖最后由 WHY 于 2022-12-15 10:44 编辑
- @echo off
- REM 替换 D:\\Firefox106 为当前脚本路径
- set "p=%~dp0"
- PowerShell "$arr = (gc -Literal '%~dp0extensions.json' -Enc UTF8 -ReadCount 0) -replace '(?<=\"path\":\")(?:(?!\"path\":\").)*(?=Profiles\\\\extensions|browser\\\\features)', '%p:\=\\%'; sc -Literal '%~dp0Result.json' -Value $arr -Enc UTF8"
- pause
复制代码
Test.ps1- #替换 D:\\Firefox106 为当前当前脚本路径
- #需PowerShell v3.0及以上版本
- $MyPath = $MyInvocation.MyCommand.Path -replace '\\[^\\]+$', '\';
- $json = gc -Literal ($MyPath + 'extensions.json') -Raw -Enc utf8 | ConvertFrom-Json;
-
- forEach( $obj In $json.addons ){
- $path = $obj.path -replace '^.*?\\(?=Profiles\\extensions|browser\\features)', $MyPath;
- $obj.path = $path;
- }
-
- $json | ConvertTo-Json -Depth 10 | sc -Literal ($MyPath + 'Result.json') -Enc utf8;
复制代码
作者: terse 时间: 2022-11-28 15:26
提取含browser\features\ 关键词的路径- @if(0)==(0) @echo off
- set "file=extensions.json"
- set "s=\browser\features\"
- cscript.exe -NoLogo -E:JScript %0 "%file%" "%s%"
- PAUSE & exit/b
- rem 保存为ANSI文件
-
- @end
-
- function adoLoadText(filename, charset) {
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset = charset;
- stream.open();
- stream.loadFromFile(filename);
- text = stream.readText(-1);
- stream.close();
- return(text);
- }
-
- var file = WSH.Arguments.Item(0);
- var jsontext =adoLoadText(file, "UTF-8");
- var obj = new Function("return" + unescape(jsontext))();
- var re = new RegExp(WSH.Arguments.Item(1).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
- for (var k in obj) {var arr = obj[k] }
- for (var i=0, len = arr.length; i<len;i++) {
- var path=arr[i]["path"]
- if (re.test(path)) {WSH.Echo(path)}
- }
复制代码
作者: kidzgy 时间: 2022-11-28 19:30
回复 kidzgy
下载gawk( )
执行结果
hfxiang 发表于 2022-11-28 09:46
您好!这个似乎是搞错了,不是提取json的path路径哦,是还要针对 D:\firefox106 进行重置路径。不知道gawk能直接修改吗?
作者: kidzgy 时间: 2022-11-28 20:00
回复 13# WHY - @echo off
- REM 替换 D:\\Firefox106 为当前脚本路径
- set "p=%~dp0"
- PowerShell "$arr = (gc -Literal '%~dp0extensions.json' -Enc UTF8 -ReadCount 0) -replace '(?<=\"path\":)(?:(?!\"path\":).)*(?=Profiles\\\\extensions|browser\\\\features)', '%p:\=\\%'; sc -Literal '%~dp0Result.json' -Value $arr -Enc UTF8"
- pause
复制代码
这段代码中的【'%p:\=\\%'】似乎应该修改为【'\"%p:\=\\%'】,不然的话,少了个双引号。path的参数无法配对。
ps的-replace 参数好奇怪, 【-replace A,B】 把A替换成B,【'\"%p:\=\\%'】是Firefox106的路径,怎么没有把【Profiles\\\\extensions|browser\\\\features】一并替换掉呢?
作者: WHY 时间: 2022-11-28 20:12
回复 16# kidzgy
确实,少加了一个双引号。- (?=Profiles\\\\extensions|browser\\\\features)
复制代码
与- (?:Profiles\\\\extensions|browser\\\\features)
复制代码
是有区别的
作者: kidzgy 时间: 2022-11-28 20:19
回复 12# WHY
刚刚试了一下,fr不支持,不过这个语句在regex101,提示回溯过多
作者: WHY 时间: 2022-11-28 20:36
本帖最后由 WHY 于 2022-12-15 10:43 编辑
回复 18# kidzgy
12楼仅仅是示例,可以无视。这样即可:- (?<="path":")(?:(?!"path":").)*(?=Profiles\\\\extensions|browser\\\\features)
复制代码
作者: hfxiang 时间: 2022-11-28 20:43
回复 15# kidzgy
所谓“重置”,无非是部分“删除”、“替换”以及“插入”,对吧?请把前后对照摆出来,awk或sed就为此而生的
作者: kidzgy 时间: 2022-11-28 21:00
回复 20# hfxiang
源代码是:- "path":"D:\\Firefox106\\Profiles\\extensions\\s3google@translator.xpi","path":"D:\\Firefox106\\browser\\features\\screenshots@mozilla.org.xpi",,"path":"D:\\Firefox106\\browser\\features\\webcompat@mozilla.org.xpi",
复制代码
假设我当前文件夹是【E:\FF\Firefox107】(注:当前路径是变量,是任意路径)
要做的就是把【D:\\Firefox106】变为【E:\FF\Firefox107】
最终效果的代码是:- "path":"E:\\FF\\Firefox107\\Profiles\\extensions\\s3google@translator.xpi","path":"E:\\FF\\Firefox107\\browser\\features\\screenshots@mozilla.org.xpi",,"path":"E:\\FF\\Firefox107\\browser\\features\\webcompat@mozilla.org.xpi",
复制代码
谢谢!
作者: terse 时间: 2022-11-28 21:23
本帖最后由 terse 于 2022-11-28 21:26 编辑
先ECHO 看这样替换成功不 (没写入文件)- @if(0)==(0) @echo off
- set "file=extensions.json"
- set "oid=%cd%"
- set "s=(?=\Profiles\extensions\|\browser\features\)"
- cscript.exe -NoLogo -E:JScript %0 "%file%" "%s%" "%oid%"
- PAUSE & exit/b
- rem 保存为ANSI文件
-
- @end
-
- function adoLoadText(filename, charset) {
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset = charset;
- stream.open();
- stream.loadFromFile(filename);
- text = stream.readText(-1);
- stream.close();
- return(text);
- }
- var s = WSH.Arguments.Item(1);
- var p = WSH.Arguments.Item(2);
- var file = WSH.Arguments.Item(0);
- var jsontext =adoLoadText(file, "UTF-8");
- var obj = new Function("return" + unescape(jsontext))();
- var re = new RegExp(s.replace(/\\/g, "\\$&"));
- var reg =new RegExp( '('+ '.+?' + ')'+ s.replace(/\\/g, "\\$&"));
- for (var k in obj) {var arr = obj[k] }
- for (var i=0, len = arr.length; i<len;i++) {
- var path=arr[i]["path"];
- if (re.test(path))
- {
- WSH.Echo( path.replace( reg, function($a,$b) { return( p ) } ) );
- }
- }
复制代码
作者: WHY 时间: 2022-11-28 21:39
gawk 肯定可以的,毋庸置疑。不过,好多好多斜杠啊
http://bcn.bathome.net/tool/4.1.0/gawk.exe- @echo off
- set "p=%~dp0"
- gawk "{print $0=gensub(/(\"path\":\")[^^\"]+(Profiles\\\\extensions|browser\\\\features)/,\"\\1%p:\=\\\\\\\\%\\2\",\"g\")}" extensions.json > a.json
- pause
复制代码
作者: kidzgy 时间: 2022-11-28 21:41
回复 22# terse
这个替换成功!如果要写入文件的话不知怎么处理呢?
作者: kidzgy 时间: 2022-11-28 21:44
回复 8# Batcher
对源文件 sed处理后的效果是这样的
作者: kidzgy 时间: 2022-11-28 21:49
回复 23# WHY
效果图是
作者: WHY 时间: 2022-11-28 21:56
本帖最后由 WHY 于 2022-11-28 21:59 编辑
回复 26# kidzgy
set "p=%~dp0"
这一句你丢了,并且要存为bat脚本文件运行
作者: kidzgy 时间: 2022-11-28 22:05
回复 27# WHY
是哈,是我大意了!感谢!非常完美!
作者: kidzgy 时间: 2022-11-28 23:49
本帖最后由 kidzgy 于 2022-11-29 02:09 编辑
回复 27# WHY
请教一下,gawk有没有办法直接修改源文件,而不是再生成新文件?另外,如何开启忽略大小写?
作者: terse 时间: 2022-11-29 01:14
Ps- <# :
- @echo off
- PowerShell -NoProfile -C ". ([ScriptBlock]::Create((gc -Literal '%~f0') -join \"`r`n\"))"
- pause & exit/b
- #>
- $oid = [Io.Directory]::GetCurrentDirectory()
- $jointxt = @(CAT .\extensions.json -Encoding UTF8)|ConvertFrom-Json
- $pat ='^.*?\\(?=Profiles\\extensions|browser\\features)'
- for ( $i=0; $i -lt $jointxt.addons.Count;$i++) {
- $jointxt.addons[$i].path = $jointxt.addons[$i].path -replace $pat,$oid
- }
- $jointxt|ConvertTo-Json | sc 'New_extensions.json' -Encoding UTF8
复制代码
作者: WHY 时间: 2022-11-29 13:26
回复 29# kidzgy
比如,把 1.txt 中的 abc 改成 xyz- gawk -v "IGNORECASE=1" "{print $0=gensub(/abc/,\"xyz\",\"g\")>\"1.txt\"}" 1.txt
复制代码
作者: kidzgy 时间: 2022-11-29 19:15
回复 30# terse
这个管用,谢谢!感觉ps比bat+第三方复杂好多!
作者: kidzgy 时间: 2022-11-29 19:26
回复 31# WHY
感谢!!现在是更加完善了!
作者: terse 时间: 2022-11-29 21:06
回复 33# kidzgy
直接正则替换效率提高的 练手一下
PS- <# :
- @echo off
- PowerShell -NoProfile -C ". ([ScriptBlock]::Create((gc -Literal '%~f0') -join \"`r`n\"))"
- pause & exit/b
- #>
- $oid = [Io.Directory]::GetCurrentDirectory() -replace '\\','\\'
- $pat = '(?<="path":")[^"]+(?=\\\\Profiles\\\\extensions\\\\|\\\\browser\\\\features\\\\)'
- $(gc extensions.json -Raw -Encoding UTF8) -replace $pat , $oid | sc 'extensions.json' -Encoding UTF8
复制代码
JS代码长,效率不低- @if(0)==(0) @echo off
- set "file=extensions.json"
- set "ph=%~dp0"
- cscript.exe -NoLogo -E:JScript %0 "%file%" "%ph:~,-1%"
- PAUSE & exit/b
- @end
- function adoLoadText(filename, charset) {
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset = charset;
- stream.open();
- stream.loadFromFile(filename);
- text = stream.readText(-1);
- stream.close();
- return(text);
- }
-
- function adoSaveText(filename, text) {
- var stream;
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset ='utf-8';
- stream.open();
- stream.writeText(text);
- stream.saveToFile(filename, 2);
- stream.close();
- }
-
- var file = WSH.Arguments.Item(0);
- var p = WSH.Arguments.Item(1).replace(/\\/g,"\\\\");
- var jsontext =adoLoadText(file, "UTF-8");
- var re =/("path":")[^"]+(?=\\\\Profiles\\\\extensions\\\\|\\\\browser\\\\features\\\\)/ig;
- adoSaveText('extensions.json',jsontext.replace( re, function($a,$b ) {return($b+p)}));
复制代码
作者: kidzgy 时间: 2022-11-29 22:38
回复 34# terse
第二段代码提示(UTF-8编码)- 输入错误: 无法找到脚本文件“D:\Firefox107 - 副本\profiles\123.bat聽聽extensions.json”。
复制代码
或者(GBK编码或ANSI编码)- CScript 错误: 加载脚本“D:\Firefox107 - 副本\profiles\123.bat??extensions.json”失败(文件名、目录名 或卷标语法不正确。 )。
复制代码
作者: terse 时间: 2022-11-30 00:11
回复 35# kidzgy
我这边测试的是你发的extensions.json文件,都通过测试,系统win10
会不会文件编码问题
作者: kidzgy 时间: 2022-11-30 18:06
回复 36# terse
我知道是什么原因了,是我火狐浏览器的问题,107版本在复制时,会有【<0xa0>】 的特别空白符,导致批处理运行失败。在106版本或换成EDGE浏览器时则无此情况,这应该是火狐107独有的BUG。
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |