无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 721|回复: 26
打印 上一主题 下一主题

[已解决] 请教一个正则表达式该如何写?(已解决)

[复制链接]
跳转到指定楼层
1#
发表于 2024-9-27 09:07:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 likeyouli 于 2024-9-27 16:29 编辑

  以解决,谢谢7楼。
待搜索内容:
zlib-1.2.7-18.el7.x86_64.gpm
zlib-devel-1.2.7-18.el7.i686.rpm
zlib-devel-1.2.7-18.el7.x86_64.rpm
zlib-static-1.2.7-18.el7.i686.rpm
zlib-static-1.2.7-18.el7.x86_64.rpm
zsh-5.0.2-34.el7_8.2.x86_64.rdm
zsh-html-5.0.2-34.el7_8.2.x86_64.rpg
zziplib-0.13.62-12.el7.i686.rpm
zziplib-0.13.62-12.el7.x86_64.rpm
zziplib-devel-0.13.62-12.el7.i686.rpm
zziplib-devel-0.13.62-12.el7.x86_64.rpm
zziplib-utils-0.13.62-12.el7.x86_64.rpm

   匹配以 “.rpm” 结尾的除了“.rpm”之外的内容,如:zziplib-devel-0.13.62-12.el7.i686.rpm,我只想匹配出 zziplib-devel-0.13.62-12.el7.i686
    不知道这个正则表达式该怎样写 ?  百度搜索出来的,请先测试后再回帖,因为我也百度了好多次,测试后发现都不行。
     7楼的可以:.*(?=\.rpm$)    (?=xxx) 表示在xxx前边
——————————————————————————————————————————————————————————————————————————————————————————————————————————————
  以上为原题,升级为以下题目,centos系统(iso镜像)挂载后(顺便说一下挂载命令①mkdir /likeyou,根目录下创建likeyou文件夹;②mount /dev/cdrom /likeyou 提示:mount: /dev/sr0 写保护,将以只读方式挂载。重新进入likeyou文件夹即可看到挂载的文件。),打开Packages文件夹,ls,会看到以下类似包:
yum-plugin-versionlock-1.1.31-54.el7_8.noarch.rpm
yum-rhn-plugin-2.0.1-10.el7.noarch.rpm
yum-updateonboot-1.1.31-54.el7_8.noarch.rpm
yum-utils-1.1.31-54.el7_8.noarch.rpm
zenity-3.28.1-1.el7.x86_64.rpm
zip-3.0-11.el7.x86_64.rpm
zlib-1.2.7-18.el7.i686.rpm
zlib-1.2.7-18.el7.x86_64.rpm
zlib-devel-1.2.7-18.el7.i686.rpm
zlib-devel-1.2.7-18.el7.x86_64.rpm
zlib-static-1.2.7-18.el7.i686.rpm
zlib-static-1.2.7-18.el7.x86_64.rpm
zsh-5.0.2-34.el7_8.2.x86_64.rpm
zsh-html-5.0.2-34.el7_8.2.x86_64.rpm
zziplib-0.13.62-12.el7.i686.rpm
zziplib-0.13.62-12.el7.x86_64.rpm
zziplib-devel-0.13.62-12.el7.i686.rpm
zziplib-devel-0.13.62-12.el7.x86_64.rpm
zziplib-utils-0.13.62-12.el7.x86_64.rpm
  要求:提取每行中以.rpm结尾、倒数第一个.与倒数第二个点之间的内容,也就是类似x86_64、i686、noarch这样的内容,这些其实代表的是这个包支持的架构。
我发现提取的方式多种多样,比如用cut、rev,awk,有些还得配合正则表达式才能完成,但仅用一个表达式就能提取出来的只有正则表达式:
   ls|grep -Po '[^\.]+(?=\.rpm$)'   然后就可以|sort|uniq -c  排序、去重并统计重复个数。

     正则表达式魅力无限啊
         又想到一个题目:不管最后一个.后边是不是rpm,我就要求取倒数第一个.与倒数第二个.之间的内容,也就是类似x86_64、i686、noarch这样的内容,可以这样写:  ls|grep -Po '[^.]+(?=\.[^.]+$)'     , 多次测试,发现[ ] 这里边无论写. 还是写\. 好像都行,难道中括号里边的. 就是点,而不是元字符?经过测试发现,反选时中括号里边[^.] 与 [^\.] 表示的意思一样,都是表示除了点之外的内容。______________________________________________________________________________________________
继续发散:如果要取倒数第二个点与倒数第三个点之间的内容呢 ?也就是el7,那就可以这样写:
ls|grep -P '[^.]+(?=\.[^.]+\.[^.]+$)'      ,正则表达式实在太灵活了,有了它,还要什么awk啊, 据说awk取列还相当复杂,除了awk取的列能直接运算、能重新排列,除此之外,单纯提取内容相对于正则表达式就是渣。



2#
发表于 2024-9-27 09:39:59 | 只看该作者
文心一言的回答,供你参考:
要匹配以“.rpm”结尾的字符串,但只保留到“.rpm”之前的部分,你可以使用正则表达式中的“捕获组”功能,并结合“非贪婪匹配”来确保只匹配到最后一个“.rpm”之前的所有内容。但是,由于你实际上是在使用正则表达式来提取信息,而不是进行简单的匹配,因此你需要使用支持捕获组功能的工具或编程语言。

在大多数正则表达式引擎中,你可以使用以下模式:

regex
^(.*?)\.rpm$
这里的^表示字符串的开始,(.*?)是一个非贪婪的捕获组,它会匹配尽可能少的字符,直到遇到后面的模式(这里是.rpm),.rpm直接匹配文本“.rpm”,$表示字符串的结束。

但是,请注意,这个正则表达式假设整个字符串就是你想要匹配的那一行,即每行只有一个以“.rpm”结尾的字符串。如果你的环境(如某些文本编辑器或编程语言)支持这种正则表达式,并且你正在逐行处理这些字符串,那么这个正则表达式就能工作得很好。

然而,如果你是在一个不支持直接提取捕获组内容的简单文本搜索环境中(比如某些简单的文本编辑器或命令行工具),你可能需要采用其他方法,比如使用支持正则表达式的命令行工具(如grep配合sed或awk)来提取这些信息。

例如,在bash中使用grep和sed组合来提取每行中“.rpm”之前的部分:

bash
grep -oP '^(.*?)\.rpm$' yourfile.txt | sed 's/\.rpm$//'
这里,grep -oP选项允许你使用Perl兼容的正则表达式(PCRE),并只输出匹配的部分。sed 's/\.rpm$//'用于移除每行末尾的“.rpm”。但是,请注意,由于你的示例中每行只有一个以“.rpm”结尾的字符串,这个命令实际上会按行输出每个匹配项(即每行一个结果),并且已经移除了“.rpm”后缀。

如果你的环境或工具不支持这些选项,你可能需要查找特定于该环境的解决方案。

点评

你是用的 sed 's/\.rpm$//' 算是绕道,不是仅用正则表达式。  详情 回复 发表于 2024-9-27 09:47
回复

使用道具 举报

3#
发表于 2024-9-27 09:47:05 | 只看该作者
对于单行,^(.*?)\.rpm$。多行怎么弄?

点评

看准题,不要匹配出 .rpm  详情 回复 发表于 2024-9-27 09:51
回复

使用道具 举报

4#
 楼主| 发表于 2024-9-27 09:47:37 | 只看该作者
scq330 发表于 2024-9-27 09:39
文心一言的回答,供你参考:
要匹配以“.rpm”结尾的字符串,但只保留到“.rpm”之前的部分,你可以使用正 ...

你是用的 sed 's/\.rpm$//'  算是绕道,不是仅用正则表达式。
回复

使用道具 举报

5#
 楼主| 发表于 2024-9-27 09:51:30 | 只看该作者
zlq_hysy 发表于 2024-9-27 09:47
对于单行,^(.*?)\.rpm$。多行怎么弄?

看准题,不要匹配出 .rpm

点评

没错呀,匹配 .rpm前面的。  详情 回复 发表于 2024-9-27 09:59
回复

使用道具 举报

6#
发表于 2024-9-27 09:59:18 | 只看该作者
本帖最后由 zlq_hysy 于 2024-9-27 10:41 编辑
likeyouli 发表于 2024-9-27 09:51
看准题,不要匹配出 .rpm

没错呀,匹配 .rpm前面的。
au3写的代码:

点评

你这貌似用()分的组, 然后取的【0】,也就是第一组,所以看似匹配成功了,但仅从正则表达式来看,也把.rpm匹配出来了。  详情 回复 发表于 2024-9-27 10:46
回复

使用道具 举报

7#
发表于 2024-9-27 10:11:54 | 只看该作者
加一个非捕获组。
  1. .*(?=\.rpm$)
复制代码

点评

感谢,可以。  发表于 2024-9-27 10:42
回复

使用道具 举报

8#
发表于 2024-9-27 10:12:42 | 只看该作者
grep -oP .+(?=.rpm$) t.txt
批处理的for更方便,不需要第三方软件

点评

谢谢,如果用excel更方便,left len函数一嵌套就行, grep -oP .+(?=.rpm$) .前边必须要用\转义吧,否则仅代表一个字符, 如果有zziplib-devel-0.13.62-12.el7.i686rpm 就会匹配出zziplib-devel-0.13.62-12.el7  详情 回复 发表于 2024-9-27 10:36
回复

使用道具 举报

9#
发表于 2024-9-27 10:20:31 | 只看该作者
前面说
匹配以 “.rpm” 结尾

后面又说
除了“.rpm”之外的内容

最后结果却是:
zziplib-devel-0.13.62-12.el7.i686

反正我脑袋大了。感觉前后矛盾啊。

点评

意思是:找到以“.rpm”结尾的行,然后删除‘.rpm’,取剩余的字串  详情 回复 发表于 2024-9-27 10:36
表述错了吗 ? 匹配以 “.rpm” 结尾 ,意思是查找的每行内容中必须以 .rpm结尾; 除了“.rpm”之外的内容,我又不想要.rpm 这几个字 两个条件,不矛盾啊  详情 回复 发表于 2024-9-27 10:28
回复

使用道具 举报

10#
 楼主| 发表于 2024-9-27 10:28:47 | 只看该作者
本帖最后由 likeyouli 于 2024-9-27 10:38 编辑
tt911 发表于 2024-9-27 10:20
前面说

后面又说

表述错了吗 ?
匹配以 “.rpm” 结尾 ,意思是查找的每行内容中必须以 .rpm结尾,看搜索内容,有的行不以.rpm结尾,这样的行首先排除了;
除了“.rpm”之外的内容,我又不想要.rpm 这几个字,,嗯,之外这两个字多余,每行中除了“.rpm”后剩余的内容
  两个条件,不矛盾啊
回复

使用道具 举报

11#
 楼主| 发表于 2024-9-27 10:36:24 | 只看该作者
szwp 发表于 2024-9-27 10:12
grep -oP .+(?=.rpm$) t.txt
批处理的for更方便,不需要第三方软件

谢谢,如果用excel更方便,left len函数一嵌套就行,
grep -oP .+(?=.rpm$)     .前边必须要用\转义吧,否则仅代表一个字符, 如果有zziplib-devel-0.13.62-12.el7.i686rpm 就会匹配出zziplib-devel-0.13.62-12.el7.i68,但这行是不符合.rpm结尾要求的。

点评

如果直接针对某一目录的,就不需要先生成文件列表了。多试试总会成功的。  详情 回复 发表于 2024-9-27 10:44
回复

使用道具 举报

12#
发表于 2024-9-27 10:36:58 | 只看该作者
tt911 发表于 2024-9-27 10:20
前面说

后面又说

意思是:找到以“.rpm”结尾的行,然后删除‘.rpm’,取剩余的字串
回复

使用道具 举报

13#
发表于 2024-9-27 10:44:43 | 只看该作者
likeyouli 发表于 2024-9-27 10:36
谢谢,如果用excel更方便,left len函数一嵌套就行,
grep -oP .+(?=.rpm$)     .前边必须要用\转义吧, ...

如果直接针对某一目录的,就不需要先生成文件列表了。多试试总会成功的。
回复

使用道具 举报

14#
 楼主| 发表于 2024-9-27 10:46:01 | 只看该作者
zlq_hysy 发表于 2024-9-27 09:59
没错呀,匹配 .rpm前面的。
au3写的代码:

你这貌似用()分的组,
然后取的【0】,也就是第一组,所以看似匹配成功了,但仅从正则表达式来看,也把.rpm匹配出来了。

点评

是的老大,例子只是一个单一的字串的捕获,第二句的au3函数返回的是一个只有一个元素的数组。  详情 回复 发表于 2024-9-27 11:07
回复

使用道具 举报

15#
发表于 2024-9-27 11:07:05 | 只看该作者
likeyouli 发表于 2024-9-27 10:46
你这貌似用()分的组,
然后取的【0】,也就是第一组,所以看似匹配成功了,但仅从正则表达式来看,也 ...

是的老大,例子只是一个单一的字串的捕获,第二句的au3函数返回的是一个只有一个元素的数组。
回复

使用道具 举报

16#
发表于 2024-9-27 11:09:57 | 只看该作者
需要用到正则表达式的顺序环视
回复

使用道具 举报

17#
发表于 2024-9-27 13:12:58 | 只看该作者
谢谢7楼分享
回复

使用道具 举报

18#
发表于 2024-9-27 13:32:56 | 只看该作者
来了解下
回复

使用道具 举报

19#
发表于 2024-9-27 13:42:25 | 只看该作者
要是我的话,我直接用前瞻引用了。
书中太高级的部分,没整明白。
学习了。
回复

使用道具 举报

20#
发表于 2024-9-27 14:21:54 | 只看该作者
学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-15 15:51

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表