如何做一个重音不敏感的grep?

 手机用户2502854107 发布于 2023-02-06 13:37

有没有办法使用grep进行重音不敏感搜索,最好保留--color选项?通过这个我的意思grep --secret-accent-insensitive-option aei是匹配àei,但也äēì和可能æi.

我知道我可以iconv -t ASCII//TRANSLIT用来删除文本中的重音,但我不知道如何使用它来匹配文本被转换(它适用于grep -c或-l)

1 个回答
  • (道歉双张贴,但这绝对是一个明显的答案. 这也是正确的答案.我只是刚刚学会的这几分钟前.)


    您正在寻找一大堆POSIX正则表达式等价类:

    14.3.6.2等价类运算符([= … =])

    正则表达式识别列表中的等价类表达式.甲等价类表达是一组核对这都属于同一等价类别的元素.通过在open-equivalence-class操作符close-equivalence-class操作符之间放置一个collat​​ing元素,可以形成一个等价类表达式.[=表示open-equivalence-class运算符,=]表示close-equivalence-class运算符.例如,如果aA是一个等价类,那么这两个[[=a=]][[=A=]]将匹配都aA.如果等价类表达式中的整理元素不是等价类的一部分,则匹配器会将等价类表达式视为整理符号.

    我在下一行使用插入符号来指示实际着色的内容.我还调整了测试字符串来说明关于案例的观点.

    $ echo "I match àei but also ä?ì and possibly æi" | grep '[[=a=]][[=e=]][[=i=]]'
    I match àei but also ä?ì and possibly æi
            ^^^          ^^^
    

    这匹配所有单词aei.它不匹配的事实æi应该提醒你,你对正在使用的正则表达式库中存在的任何映射感兴趣(可能是gnulib,这是我链接和引用的),尽管我认为它很可能是有向图的即使是最好的等价类地图也无法触及.

    你不应该期望等价类是可移植的,因为它们太神秘了.


    更进一步,如果你只需要重音字符,事情会变得复杂得多.在这里,我已将您的请求更改aei[aei].

    $ echo "I match àei but also ä?ì and possibly æi" | grep '[[=a=][=e=][=i=]]'
    I match àei but also ä?ì and possibly æi
    ^  ^    ^^^     ^    ^^^ ^       ^     ^
    

    清除它以避免非重音匹配需要等价类和前瞻/后视,而BRE(基本POSIX正则表达式)和ERE(扩展POSIX正则表达式)支持前者,它们都缺少后者.Libpcre(Perl兼容正则表达式的C库grep -P以及大多数其他人使用的)并perl支持后者但缺少前者:

    尝试#1: grep使用libpcre: 失败

    $ echo "I match àei but also ä?ì and possibly æi" \
        | grep -P '[[=a=][=e=][=i=]](?<![aei])'
    grep: POSIX collating elements are not supported
    

    尝试#2: perl本身:失败

    $ echo "I match àei but also ä?ì and possibly æi" \
        | perl -ne 'print if /[[=a=][=e=][=i=]](?<![aei])/'
    POSIX syntax [= =] is reserved for future extensions in regex; marked by <-- HERE in m/[[=a=][=e= <-- HERE ][=i=]](?<![aei])/ at -e line 1.
    

    尝试#3 :( python有自己的PCRE实现):( 无声)失败

    $ echo "I match àei but also ä?ì and possibly æi" \
        | python -c 'import re, sys;
                     print re.findall(r"[[=a=][=e=][=i=]]", sys.stdin.read())'
    []
    

    哇,PCRE的正则表达式功能,python甚至perl 支持!这些并不多.(别担心投诉是关于第二个等价类,它仍然只是抱怨/[[=a=]]/.)这是等价类是神秘的进一步证据.

    实际上,似乎没有任何 PCRE库能够进行等价类; regular-expressions.info上关于等价类的部分声称只有实现POSIX标准的正则表达式库实际上才有这种支持.GNU grep最接近,因为它可以执行BRE,ERE和PCRE,但它无法组合它们.

    所以我们将分两部分来完成.

    尝试#4:恶心的诡计:成功

    $ echo "I match àei but also ä?ì and possibly æi" \
        | grep --color=always '[[=a=][=e=][=i=]]' \
        | perl -pne "s/\e\[[0-9;]*m\e\[K(?i)([aei])/\$1/g"
    I match àei but also ä?ì and possibly æi
            ^            ^^^
    

    代码行走:

    grep强制颜色打开,以便perl键入颜色代码以记录匹配

    ${GREP_COLOR:-01;31}音符grep的颜色(默认为相同的亮红色)

    perls///命令匹配完整的颜色代码,然后匹配我们想要从最终结果中删除的非重音字母.它用(未着色的)字母替换所有这些

    (?i)perl正则表达式之后的任何事情都是因为[[=i=]]匹配而不区分大小写I

    perl -p在完成-e执行后打印其输入的每一行


    有关BRE vs ERE与PCRE和其他人的更多信息,请参阅这个StackExchange正则表达式帖子或者regular-expressions.info上的POSIX 正则表达式.有关每种语言差异的更多信息(包括libpcre与python PCRE vs perl),请查看regular-expressions.info上的工具.

    2023-02-06 13:39 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有