【问题标题】:Using bash grep -Po regex fails if string has an underscore如果字符串有下划线,则使用 bash grep -Po 正则表达式失败
【发布时间】:2013-07-25 17:12:00
【问题描述】:

我已经搜索甚至 gasp 阅读了手册页,但我仍然无法弄清楚这是怎么回事以及如何解决它......我承认自己是一个正则表达式新手,所以没有羞耻! (Ubuntu 12.04、bash 4.2.25、GNU grep 2.10)

作为脚本的一部分,它执行了许多其他有趣的事情(这些事情似乎都有效),我正在尝试从文件名中提取数据......存在某些预期的模式......例如一些文件名会有一个日期:日期的格式是“YYYY-MM-DD”,我可以轻松地找出整个事情,然后用'\b[0-9]{4}.{1}[0-9]{2}.{1}[0-9]{2}\b' grepping 来分解它(实际上我通常可以安全地直接用@ 定位年份987654322@ ) 如果输入字符串看起来像以下任何一个,这可以正常工作:

something 1989-07-23 something.jpg" or "foo-2013-01-10-bar.csv

但如果它看起来像 wordsidon'tcareabout_2004-09-14_otherthings.tif 或这个 foofoobarbar_2010-07-16.gif grep 找不到匹配项。

下划线是什么意思?为什么它们会导致我的正则表达式失败?有没有更好的方法来解决这个问题,我可能不知道?我有极少的 perl 和 java 技能,但我对 bash 非常了解......或者我认为我知道......

我想我可以重命名文件,但这似乎不优雅。

【问题讨论】:

    标签: regex bash grep localization collation


    【解决方案1】:

    您的正则表达式使用\b,它匹配单词和非单词字符之间的边界。问题是_是单词字符,数字也是,所以_2之间没有界限。

    你可以使用

    [^0-9][0-9]{4}.{1}[0-9]{2}.{1}[0-9]{2}[^0-9]
    

    相反。如果日期可以在文件名的开头或结尾,请使用:

    ([^0-9]|^)[0-9]{4}.{1}[0-9]{2}.{1}[0-9]{2}([^0-9]|$)
    

    【讨论】:

    • 啊哈!这意味着我不能再直接定位年份,因为 '[0-9]{4}' 还会在 123456-1942-07-11-foobar.txt 中找到我不想要的匹配项,但我认为我可以工作省略边界。谢谢! (该死的,鬼鬼祟祟的字字符!)
    • 您可以将[^0-9] 替换为列出您希望允许作为边界的特定字符的字符类。
    猜你喜欢
    • 2011-04-06
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多