如题,我有一批文档,每个文档开头都有一段文字,以其中一个为例
---
Tag(s): /I/-/文/学/ /I/7/./1/./2/./0/美/国/文/学/ /I/7/./1/./0/北/美/文/学/ /I/7/./1/./2/./1/./0/诗/歌/、/韵/文/ /I/7/-/美/洲/文/学/ /I/7/./1/./2/./1/./0/2/0/W/a/l/t/-/W/h/i/t/m/a/n/(/1/8/1/9/-/1/8/9/2/)/
---
我的需求是
1.将---
之间的tag部分的/
批量删除
2.将tag部分的半角空格
替换为/
3.将这部分的.
替换为_
4.对这一批文档(大概几千个)批量进行上述处理
目前比较习惯用的文本编辑器有notepad++和emeditor,但只能对整篇文档进行处理,绞尽脑汁也想不到怎么将指定部分的文本替换,但又不“误伤”其他文档内其他文本的的方法,希望有熟悉的朋友能不吝赐教,谢谢谢谢!
dms
2
首先要说明正则不是万能的,在某些角度下它是有很大局限性的,所以千万不要认为任何查找替换类的问题都可以用正则去解决,或者都适合用正则去解决。也许用脚本分几次去进行处理,效率更高。
然后回到这个问题,先假设你所给出的这段示例没有进行任何精简。
那么我们可以先提取特征,这里有三行文字:
- 第 1 行是:
---
- 第 2 行是:
Tag(s):
开头的文字
- 第 3 行是:
---
上面这些特征是用来识别的,而它本身并不发生改变,这时候可以使用断言。但这时候就又要说到各种编辑器以及各种编程语言,对于正则的支持是不相同的(甚至在语法上都有一定的区别),在有些编辑器或者有些语言下是没有办法使用断言的……
仍然要使用正则的话,可能只好每次只处理一处替换,然后不断重复操作,直至所有需要修改的地方都被修改完成。
所以比较方便的方法还是使用脚本,用正则确定出这三行,然后再把这些内容交给下一步去进行处理,这样能简单好多,效率也能提升好多。
runze
4
notepad3 可以,但是一次只能替换一处,需要连续执行很多次
loli
7
首先确认这是你要的效果
---
Tag(s):/I-文学/I7_1_2_0美国文学/I7_1_0北美文学/I7_1_2_1_0诗歌、韵文/I7-美洲文学/I7_1_2_1_020Walt-Whitman(1819-1892)
---
然后确认每个Tag(s):都在第二行(不在没事,只不过会跳过修改)
然后下载个AHKV2
https://www.autohotkey.com/download/2.0/
或者直接下载
https://www.autohotkey.com/download/2.0/AutoHotkey_2.0-beta.1.zip
解压里面的AutoHotkeyU64.exe到任意文件夹(比方说桌面)
然后在这个文件夹新建个文件保存下面的代码
然后在脚本最开始的地方设置自己的路径及文件格式
然后拖拽这个脚本文件到AutoHotkeyU64.exe上
最好测试下随便复制几篇到一个文件夹,然后针对这个文件夹测试
脚本是遍历子文件夹的
path := "F:\Documents\Desktop\新建文件夹" ;文件路径
ext := "txt" ;文件格式
Loop Files path "/*." ext, "R"
{
FileObj := FileOpen(A_LoopFileFullPath, "r")
all := FileObj.Read()
FileObj.Seek(0,0)
FileObj.ReadLine()
line := FileObj.ReadLine()
if !InStr(line,"Tag(s)")
continue
line2 := StrReplace(line, "/", "")
line2 := StrReplace(line2, " ", "/")
line2 := StrReplace(line2, ".", "_")
end := StrReplace(all,line, line2)
FileObj.Close()
FileDelete(A_LoopFileFullPath)
FileAppend(end,A_LoopFileFullPath)
all := line := line2 := end := ""
}
1 个赞
loli
8
如果不是每个Tag(s):都在第二行 可以试试这个
path := "F:\Documents\Desktop\新建文件夹" ;文件路径
ext := "txt" ;文件格式
Loop Files path "/*." ext, "R"
{
FileObj := FileOpen(A_LoopFileFullPath, "r")
all := FileObj.Read()
FileObj.Seek(0,0)
Loop
If (FileObj.ReadLine() = "---" && InStr(line := FileObj.ReadLine(), "Tag(s):") && FileObj.ReadLine() = "---") || A_Index = 100
break
If !InStr(line, "Tag(s):")
continue
line2 := StrReplace(line, "/", "")
line2 := StrReplace(line2, " ", "/")
line2 := StrReplace(line2, ".", "_")
end := StrReplace(all,line, line2)
FileObj.Close()
FileDelete(A_LoopFileFullPath)
FileAppend(end,A_LoopFileFullPath)
all := line := line2 := end := ""
}
1 个赞
emeditor
搜索
(/(.)){1}
替换
\2
效果是这样的,感觉足够了
几个- - -被md效果遮盖了,变成了粗体
如果担心误伤,可用
搜索(/(.)){1}(/(.)){1}
替换\2\4
应该就可以的了
然后在emeditor菜单-搜索-多文件替换就可以了
Tag(s): I-文学 I7.1.2.0美国文学 I7.1.0北美文学 I7.1.2.1.0诗歌、韵文 I7-美洲文学 I7.1.2.1.020Walt-Whitman(1819-1892)/
dog
10
好吧,发现根本不用那么复杂。
一次性直接把:
/(?<=\Tag([^/\n\r]+/)+)(?=[^\n\r]*\n)
替换成空,就去掉了/,其他类似。
这段代码匹配以“Tag开头的一行里的"/"字符”,可以免除对正文部分“/”的误伤。
1 个赞
这个脚本可以替换已经打开的文件
emeditor用的,代码保存为jsee
你一次性打开多少文件就看你电脑性能了
没有撤销,备份好文件
#title="macro"
#tooltip="macro",1033,"macro",1041,"macro",1029,"macro",1031,"macro",1036,"macro",3082,"macro",2058,"macro",1040,"macro",1042,"macro",1043,"macro",1049,"macro",2052,"macro",1028
#icon=""
#status=
Redraw = false;
DiscardUndo = true;
docs01 = new Enumerator( editor.Documents );
//打开的文件循环
for( ; !docs01.atEnd(); docs01.moveNext() )
{
doc01 = docs01.item();
doc01.Activate();
strName = doc01.Name;
var _regex="html" //这里html改成你要替换的文件后辍名
var regex=new RegExp(_regex,"gim");
var textInCurrentDocument=strName;
var matchResultArray=textInCurrentDocument.match(regex);
if (matchResultArray)
{
//以下是处理片段
document.selection.StartOfDocument(false);
nFlags=eeFindNext | eeFindSelectAll;
document.selection.Find("Tag(s)",nFlags);
document.selection.StartOfLine(true,eeLineLogical);
document.selection.EndOfLine(true,eeLineLogical);
nFlags=eeFindReplaceSelOnly | eeFindNext | eeReplaceAll;
document.selection.Replace(" ","",nFlags);
document.selection.Replace("/","",nFlags);
document.selection.Replace(".","_",nFlags);
document.selection.Collapse();
//以上是处理片段
document.close();
Redraw = false;
}
else
Redraw = true;
}
dog
13
在这个网站测试没有问题,可能各个软件对正则支持不太一样。。。。。。
总之语法是这么写的,什么软件支不支持就不晓得了
dog
15
进一步研究发现,
能做到这种替换的属于deelx正则表达式引擎:
http://www.regexlab.com/zh/deelx
可以下载水淼·文件批量处理器,打开工具-正则调试器
上面选择单行,把 /(?<=Tag([^/\n\r]+/)+) 替换成空
然后点击批量替换,就可以把所有文件替换好了。
1 个赞
想问一下,这个是不是只针对tag(s)
这一行做出的处理?如果待处理的文本在标志开始的下一行,或者下几行,语句应该怎么写呢?
如果都在特定的下面几行,可以使用转跳语句
插入在下面这一句的下面
document.selection.Find(“Tag(s)”,nFlags);
具体的语句不太记得,我电脑不在旁边.
你可以去emeditor的在线帮助网页找找转跳语句.