【问题标题】:Remove sub-string from beginning of string从字符串的开头删除子字符串
【发布时间】:2015-01-28 06:58:34
【问题描述】:

我有一个代表文件完整路径的字符串:

full_path = '/home/user/fold1/fold2/sub-fold/'

我需要从这个字符串中删除它存储在一个 不同 变量中的根路径:

root = '/home/user/fold1/'

因此生成的路径应如下所示:

new_path = 'fold2/sub-fold/'

随着我的代码运行存储在许多不同位置的许多文件,完整路径(显然是根路径)不断变化。

这是我所追求的(不存在的)操作:

new_path = full_path - root

我该怎么做?

【问题讨论】:

  • full_path.replace(root, '')

标签: python string substring


【解决方案1】:

对于路径操作,最好使用os.path:

import os
new_path = os.path.relpath(full_path, root)

FTR:字符串的- 运算符的等价物是string.replace(),但正如其他人指出的那样,它将替换所有出现的字符串,而不仅仅是开头:

new_path = full_path.replace(root, '')

【讨论】:

  • 使用replace 不是一个好主意,因为它也会替换中间某处的根,这可能会导致问题,尤其是当根只是'/' 时。
【解决方案2】:

您可以剥离与根长度匹配的开头(bgoldst 的答案):

 path[len(root):]

但是你不会注意到开头是否与你期望的根不匹配。例如,如果您将/bla/foo 作为root/bar/zap/fong/tang 作为文件,那么您将得到/fong/tang,从而有效地掩盖了前一个错误。我不建议这样做。

正如 cmets 指出的那样,严格替换给定 path 中的字符串 root(Aprillion 的)也可以替换后来出现的字符串,有效地返回废话。

我建议正确替换字符串的开头

import re

result = re.sub(r'^' + re.escape(root), '', path)

这样可以避免两个陷阱。

您可能还想考虑只使用os.path.relpath(),它会根据文件系统逻辑从路径中删除给定的起点。

在任何情况下,您都应该考虑在给定的根与路径的开头不匹配的情况下您的程序应该如何运行。我提出的re 解决方案不会改变给定的路径。在大多数情况下,这将是一个有用的行为,但肯定不是在所有情况下。

【讨论】:

  • 感谢您的回答以及对其他答案的详细评论!
【解决方案3】:

如果您相信 full_path 确实以 root 开头,您可以使用简单的索引子字符串:

new_path = full_path[len(root):]

如果你不信任它,你可以先做一个 if-test 来检查,如果它不符合预期,则采取适当的措施。

【讨论】:

  • 这将掩盖路径开头与根不匹配的可能错误。
  • 不,这不会掩盖错误。我明确地用“如果你相信 full_path 确实以 root 开头”来限定我的答案,并指出如果你不信任它,你需要检查它。程序员总是有充分的理由相信变量。如果我们不这样做,我们的代码将充满不必要和浪费的检查,我们将无法完成任何工作。
  • 是的,没错。我只是不会在一个像样的解决方案之前发布一个优化的解决方案。
  • 一个优化的解决方案一个不错的解决方案。
  • 对不起,我不得不不同意这一点(实际上非​​常强烈)。在我看来,一个体面的解决方案也是下一个开发人员能够立即阅读和理解所有后果的解决方案(并且无需阅读一些说明更晦涩的文档) . 优化 解决方案可能缺少这些有利于速度或内存消耗的功能。至少,I 一开始就是这样表示decent 这个词的。如果我对这个词的使用具有误导性,我深表歉意。
【解决方案4】:

https://stackoverflow.com/a/27208635/6769234的补充

可以用第三个参数控制替换的出现次数:

"bbb_ccc_ddd_bbb_eee_bbb".replace("bbb", "", 1) # '_ccc_ddd_bbb_eee_bbb' "bbb_ccc_ddd_bbb_eee_bbb".replace("bbb", "", 2) # '_ccc_ddd__eee_bbb'

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2019-11-15
    • 2019-09-08
    相关资源
    最近更新 更多