Board logo

标题: [问题求助] [已解决]PowerShell正则表达式匹配第三行到指定字符串之前的所有行 [打印本页]

作者: wxyz0001    时间: 2021-5-18 23:55     标题: [已解决]PowerShell正则表达式匹配第三行到指定字符串之前的所有行

本帖最后由 wxyz0001 于 2021-5-19 10:01 编辑

正则表达式匹配第三行到指定字符串之前的所有行其表达式怎么写
  1. 读者文摘杂志 2013年第05期列表页
  2. 16岁出门远行
  3. 作者:丁爱波 来源:《齐鲁周刊》2012年第50期
  4.   少年派的流浪开始时,他才16岁。在我们这个时代的标签里,16岁的你青黄不接,张皇失措,寂寞孤独。
  5.   成长是一场世界观的漂流记,对那些立志改变世界的少年来说,出门远行,是认知真实世界的第一步。
  6.   1
  7.   1990年,在清华大学读了3年雷达专业后,高晓松发现自己不适合当科学家。
  8.   后来的故事很多人都知道了。高晓松与老狼“出走”海南,在一个叫“癫马”的歌厅唱了一段时间歌,然后弹尽粮绝。
  9.   贫穷、困苦无法击退他流浪的激情。每一个少年都曾一无所有,每一个少年也都曾拥有世界,正如作家江南回忆自己的大学生活时所说:“10年后回想,那时候我其实富有得像个皇帝。那时候通往食堂的路上银杏明黄如金,女生们走在落叶中裙裾起落,男生们冲她们敲打饭盆。我拥有无数时光和可能,热血上涌的时候我相信自己能征伐世界,在战马背上带着窈窕的姑娘归来。”
  10.   高晓松的流浪岁月便是如此的贫穷和富有。他把大部分钱都留给回京上学的老狼,自己流落到厦门,在厦大东边社,与各地流浪的艺术家、厦大艺术学院的单身教师们、闽南佛学院的居士,甚至携家带口的逃犯一起度过了一段恣意随性的生活;还遇见了相爱4年,教会他堂堂正正做一个男人的厦大女生X,写出了祭奠青春的《麦克》,歌唱爱情和远方的《流浪歌手的情人》等许多歌。
  11.   对高晓松来说,1990年的厦门时光几乎是他“最漫长、快乐、忧伤的一年”。高晓松说:“当年出走并不是因为勇敢坚强,而是相反,觉得社会一点都不好玩。社会和大学是对立的,我们不用交学费,学校还发钱,我们是社会的蛀虫;社会麻木不仁,是我们的噩梦。”
  12.   80后作家肖睿在其《一路嚎叫》中这样写道:“我也很年轻,我也渴望远行……我已无法再忍受,只有逃走。逃离学校、逃离父母、逃离以前的朋友与敌人,忘记暗恋的女孩,让自己永远置身在星星下面的陌生人群之中,在广阔、深邃的旷野之中毫无顾忌地放声嚎叫。”
  13.   2
  14.   1952年1月,年轻的切·格瓦拉和他的朋友艾伯特从阿根廷开始了他们漫游拉丁美洲的旅程。那个时候的格瓦拉只有23岁,还是一个主攻麻风病学的医学院学生。而艾伯特是一个只有29岁的生物化学家。探索未知事物的兴趣使他们驾着诺顿500开始了8个月的旅程。
  15.   启程时,两人只带着“半无意识风格”的堂吉诃德式的梦想,“我们根本没有想过途中会遭遇多大的艰难险阻,我们的眼里只有前方路上飞扬的尘土,而车背上的我们正风雨兼程,风驰电掣般地向北挺进。”
  16.   两人像普通年轻人一样张扬而叛逆,他们的冒险经历中,既有快乐、诙谐,也有不少自嘲:夜宿在关不紧门的林中小屋时,冲着门外奔窜的美洲狮开了一枪,结果打死的却是房东家的狗;花言巧语赢得智利小镇消防站站长3个女儿的欢心,得以暂住在消防站,半夜消防警报响起时他们也英勇地冲了出去,结果却只救了一只猫;在智利中部旅行时,利用当地群众对报纸上报道两人是“麻风病专家”的信任,到处蹭吃蹭喝,纵情欢乐。
  17.   而当这位年轻的小伙子发现了美洲大陆的现实时,他的人格和思想开始走向成熟,社会阅历也愈发丰富了。当他日益意识到民众的痛苦,而这些苦痛也成为他生命的一部分时,他萌发了改变现实的理想。
  18.   与之有着相同经历的还有接受过28次电击治疗的波西格。1968年,波西格出院后,带着10岁的儿子克里斯,进行了一次长途摩托车旅行。他把旅行的感受和思考,写成了一本书《禅与摩托车维修艺术》。
  19.   他从明尼苏达奔至加州,走遍穷乡僻壤,将所见所闻所感所思向他11岁的儿子倾吐,这个男人在游历中体悟生命的意义,获得自我拯救。
  20.   他说:“佛陀或是耶稣坐在电脑和变速器的齿轮旁边修行,会像坐在山顶和莲花座上一样自在。如果情形不是如此,那无异于亵渎了佛陀——也就是亵渎了你自己。”
  21.   切·格瓦拉通过远行达成了自己的**之路,波西格则通过旅途在另一个层面完成了一场充满现代符号的宗教救赎。
  22.   3
  23.   如今谁还会将自己的目光投向远方?
  24.   在丧失了冒险的年轻特质之后,越来越多的男孩变得“娘”起来。“屌丝”横行,“宅男”当道,在未曾见识远方风景之前,18岁的少年们把自己装扮得纤尘不染,像一只只纯洁的羔羊。
  25.   龙应台和儿子飞利浦见到朋友的时候,朋友总会盯着她的脸,问飞利浦多大了。即使是夸奖飞利浦,也是对着她说的。因为在中国人的潜意识里——许多人并没有认识到这个细节——孩子永远是孩子,即使他已经18岁,已经领着自己的女朋友回家了,对于父母来说,他依然是个孩子。
  26.   甚至有一次,龙应台要去洗手间的时候,也下意识地扭头问身边的飞利浦:要不要去厕所?飞利浦反问她:难道我连自己要不要去厕所还不知道吗?
  27.   正是这种“无微不至”的母爱绑架了这些孩子的成长旅程。回想那个你初上大学的日子,外面还下着雨,宿舍里一片混乱,每个舍友都有家长跟来。所有的回忆再怎么涂抹也是那么庸常,那不是一个闪闪发光的下午,那也不是该有的成长的序曲:你老老实实坐在那里,父亲帮你把东西拿到了五楼宿舍里,大伯开着车把你送到了学校,母亲帮你收拾衣物……
  28.   在余华的小说《十八岁出门远行》中,父亲把书包递给我,“在我脑后拍了一下,就像在马屁股上拍了一下”。
  29.   “你已经18了,你应该去认识一下外面的世界了。”父亲说。
  30.   “然后我欢快地冲出了家门,像一匹兴高采烈的马一样欢快地奔跑了起来……”
  31. 上一篇:心灵的花粉    下一篇:最美的徒劳无功
  32. 卷首语
  33. 认故乡
  34. 文苑
  35. 黏人的幸福
  36. 生活之路
  37. 荒野漫步
  38. 自传难写
  39. 十二月
  40. 书林一叶
  41. 一点一横长
  42. 真相常流失于涕泪交加中
  43. 踉跄话西游
  44. 原创精品
  45. 不靠谱的“裙摆指数”
  46. 人物
  47. 选择高贵
  48. 我的邻居吴冠中
  49. 我眼中的希特勒
  50. 比时间短,比爱情长
  51. 名人轶事
  52. 乡下人喝杯甜酒吧
  53. 删掉淫秽之处
  54. 激动的汪曾祺
  55. 大帅的演讲
  56. 杂谈随感
  57. 老人不是包袱
  58. 勤劳是一种美德吗
  59. “心理人”的时代
  60. 购买一个泡沫
  61. 读者文摘杂志
复制代码
[^\r\n]{2}    .*   (?=(上一篇.*))#匹配第二行之后和"上一篇"之前的文本块,该如何写呢?
作者: newswan    时间: 2021-5-19 01:25

本帖最后由 newswan 于 2021-5-19 14:06 编辑
  1. sed ' /a/,/b/ { /a/! /b/! p } '
复制代码
批处理 如果开启延迟替换,要转义 !
作者: Batcher    时间: 2021-5-19 09:43

回复 2# newswan
  1. sed "3,/上一篇/!d" 1.txt > 2.txt
复制代码
  1. sed -n "3,/上一篇/p" 1.txt > 2.txt
复制代码

作者: wxyz0001    时间: 2021-5-19 10:01

谢谢朋友们的回答,我已经用正则表达式匹配到了:
  1. (?<=^.*\n.*\n)([\s\S]*)(?=上一篇)
复制代码

作者: qixiaobin0715    时间: 2021-5-19 10:29

回复 4# wxyz0001
不是太了解PowerShell,PowerShell对逆序环视字符长度没限制吗?
作者: wxyz0001    时间: 2021-5-19 10:48

本帖最后由 wxyz0001 于 2021-5-19 10:50 编辑

回复 5# qixiaobin0715
这是正则表达式起的作用,正则表达式对字符串长度没有限制。
其他语言用正则表达式也可以匹配到所选文本块
作者: qixiaobin0715    时间: 2021-5-19 10:51

我是指这部分:(?<=^.*\n.*\n),逆序环视长度(*)不固定可以吗?好像好多语言都有限制的。
作者: qixiaobin0715    时间: 2021-5-19 11:03

有的书上叫:负向零宽断言
作者: wxyz0001    时间: 2021-5-19 12:01

回复 7# qixiaobin0715
我就是用的负向零宽断言,可以用* ,其中^.*\n.*\n就是固定位置
作者: wxyz0001    时间: 2021-5-19 13:44

本帖最后由 wxyz0001 于 2021-5-19 13:48 编辑
  1. $TextToAdd="## "
  2. $Pattern="上一篇"
  3. $filePath="E:\news"
  4. $Filter="*.txt"
  5. $newPath="D:\newtxt"
  6. If(!(test-path $newPath)){md D:\newtxt}
  7. Get-ChildItem -Path $filePath -Filter $Filter|ForEach-Object{
  8. $line=0
  9. $temppath=$newPath+"\"+$_.name
  10. $lastIndex=(get-content $_.FullName)|Select-String -Pattern $Pattern
  11. $fileData=(get-content $_.FullName)[2..($lastIndex.LineNumber -2)]|ForEach-Object{
  12. $line++
  13. if($line -lt 2){$TextToAdd+$_}
  14. elseif($line -ge 2){$_}
  15. }|out-file $temppath -Encoding utf8
  16. }
复制代码
上面是以前的代码,经过一段时间对Powershell的摸索,下面的代码用正则表达式简化了不少
#▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇
  1. $match="(?<=^.*\n.*\n)([\s\S]*)(?=上一篇)"
  2. $filePath="E:\news"
  3. Get-ChildItem $filePath -Filter "*.txt"|ForEach-Object{
  4. if([string](Get-Content $_|Out-String) -match $match)
  5. {
  6.    '##'+$($matches[1])|out-file -append $filePath\a.txt
  7. }
  8. }
复制代码

作者: qixiaobin0715    时间: 2021-5-19 14:26

回复 9# wxyz0001
奥,原来如此,Powershell是内置在.NET框架上的脚本语言。所以负向零宽断言不受长度上的限制,其他框架好像不行。
作者: xczxczxcz    时间: 2021-5-19 16:23

回复 10# wxyz0001


    if  感觉是多余的。  out-file 默认是unicode编码,会使文档字节增大。
  1. (ls 'e:\news\*.txt' -file).Foreach{[regex]::Match((gc $_.FullName -Raw), "(?s)(?<=(.*?\n){2}).*?(?=\r?\n上一篇)").value| ac 'e\news\a.txt' -force}
复制代码

作者: wxyz0001    时间: 2021-5-19 17:11

本帖最后由 wxyz0001 于 2021-5-19 17:32 编辑

回复 12# xczxczxcz


你的正则表达式写的非常漂亮!
另外把##加了进去,因为要用标题做目录
(ls 'e:\news\*.txt' -file).Foreach{'##'+[regex]::Match((gc $_.FullName -Raw), "(?s)(?<=(.*?\n){2}).*?(?=\r?\n上一篇)").value| ac 'e:\news\a.txt' -force}
感谢对out-file的用法解释。
作者: wxyz0001    时间: 2021-5-20 19:22

本帖最后由 wxyz0001 于 2021-5-21 17:32 编辑

回复 7# qixiaobin0715

我今天用Python试了以下,负向零宽断言不能用*,不过换了个思路,把三段都找出来然后只取中间的也是可以的获取需要的。
  1. import re
  2. with open('E:\\news\\a.txt','r',encoding='utf-8') as f:
  3. data=f.read()
  4. pattern = re.compile(r'(?<=(\n){2})(.*?)(?=(\n上一篇))', re.S)
  5. ret = re.search(pattern, data)
  6. with open("E:\\news\\b.txt", "w") as ff:
  7. ff.write('##'+ret.group(2))   #只取需要的那段
复制代码

作者: qixiaobin0715    时间: 2021-5-24 10:09

回复 14# wxyz0001
顾名思义:所谓“零宽”,表示不匹配任何字符;“断言”,表示只起到判断作用。
比如上面表达式“(?<=(\n){2})(.*?)(?=(\n上一篇))”中,对应关系为:
group(1)——(\n)
group(2)——(.*?)
group(3)——(\n上一篇)
如果表达式改为“(?<=\n{2})(.*?)(?=\n上一篇)”,对应关系就只存在group(1)——(.*?)
不知我说的对否?
作者: wxyz0001    时间: 2021-5-24 22:27

回复 15# qixiaobin0715


    差不多是这个意思,断言,说成切断要准确些,把group(0)和group(1)从中切断,零宽的部分也就是group(0),为0,就是None,也就丢弃了
作者: qixiaobin0715    时间: 2021-5-24 23:41

回复 16# wxyz0001
group(0)我不知应当叫做什么,姑且起名为全部匹配,应当整个表达式匹配的内容吧。比如说,用([a-z]+)-([0-9]+)-([A-Z]+)匹配good-147-BAD,对应关系应当是:
group(1)——good
group(2)——147
group(3)——BAD
group(0)——good-147-BAD
作者: WHY    时间: 2021-5-24 23:56

先行断言、后发断言、零宽断言、环视、预查等等,这些高大上的命名很容易把人搞蒙。
我认为只需要弄明白它的匹配原理,就不需要理会它是啥名字了。
所谓的零宽度断言,无非就是匹配符合条件的位置,而不是匹配字符,所以不会把它放到匹配组里面。

用 (?<=a)b 匹配字符串 ab
就是匹配 b 前面、a 后面的一个位置。
作者: qixiaobin0715    时间: 2021-5-25 06:20

(?<=a)b,是匹配前面是a的b字符,得到匹配的只是b;b前面为a,是得到匹配的前提条件。
作者: WHY    时间: 2021-5-25 13:01

本帖最后由 WHY 于 2021-5-27 21:15 编辑

假设字符串为 ab,作为对比:
(?<=a)b
(?<=a) 匹配 b 前面、a 后面的一个位置,这个位置类似于 \b、^、$这种锚点。把锚点存储在匹配组里显然没有意义。
匹配结果:b

(?:a)b
(?:a)匹配字符a,但匹配的字符 a 不会存储在匹配组Group[1]里面。
匹配结果:ab

(a)b
(a)匹配字符a,匹配的字符 a 存储在匹配组Group[1]中。
匹配结果:ab




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2