gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 04:11:26 24 4
gpt4 key购买 nike

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

我知道我可以使用 iconv -t ASCII//TRANSLIT从文本中删除重音符号,但我不知道如何使用它进行匹配,因为文本已转换(它适用于 grep -c 或 -l)

最佳答案

您正在寻找一大堆 POSIX 正则表达式 equivalence classes :

14.3.6.2 Equivalence Class Operators ([= … =])

    Regex recognizes equivalence class expressions inside lists. A equivalence class expression is a set of collating elements which all belong to the same equivalence class. You form an equivalence class expression by putting a collating element between an open-equivalence-class operator and a close-equivalence-class operator. [= represents the open-equivalence-class operator and =] represents the close-equivalence-class operator. For example, if a and A were an equivalence class, then both [[=a=]] and [[=A=]] would match both a and A. If the collating element in an equivalence class expression isn’t part of an equivalence class, then the matcher considers the equivalence class expression to be a collating symbol.


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

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

这匹配所有像 aei 这样的词.它不匹配的事实 æi应该提醒您注意您正在使用的正则表达式库中存在的任何映射(大概是 gnulib,这是我链接和引用的内容),尽管我认为很可能是 digraphs即使是最好的等价类图也无法达到。

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

更进一步,如果你只想要重音字符,事情会变得更加复杂。在这里,我已更改您对 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( grep -P 和大多数其他人使用的 perl 兼容正则表达式的 C 库)和 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 库;关于 equivalence classes at 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 与 ERE 与 PCRE 等的更多信息,请参阅 this StackExchange regex postPOSIX regexps at regular-expressions.info .有关每种语言差异的更多信息(包括 libpcre 与 python PCRE 与 perl),请查看 tools at regular-expressions.info .

    2019 更新: GNU Grep 现在使用 $GREP_COLORS看起来像 ms=1;41优先于较旧的 $GREP_COLOR喜欢 1;41 .这更难提取(并且很难在两者之间切换),因此我在 try #4 中修改了 perl 代码以查找任何 SGR color code而不是只键入 grep 会添加的颜色。见 revision 2 of this answer对于之前的代码。

    我目前无法验证是否 BSD grep由 Apple Mac OS X 使用,支持 POSIX 正则表达式等价类。

    关于encoding - 如何做一个重音不敏感的grep?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20937864/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com