问题:如何删除字符串的左侧部分?

我有一些简单的python代码,可在文件中搜索字符串,例如path=c:\path,其中c:\path部分可能会有所不同。当前代码是:

def find_path(i_file):
    lines = open(i_file).readlines()
    for line in lines:
        if line.startswith("Path="):
            return # what to do here in order to get line content after "Path=" ?

取得文字的简单方法是什么Path=

I have some simple python code that searches files for a string e.g. path=c:\path, where the c:\path part may vary. The current code is:

def find_path(i_file):
    lines = open(i_file).readlines()
    for line in lines:
        if line.startswith("Path="):
            return # what to do here in order to get line content after "Path=" ?

What is a simple way to get the text after Path=?


回答 0

从开始Python 3.9,您可以使用removeprefix

'Path=helloworld'.removeprefix('Path=')
# 'helloworld'

Starting in Python 3.9, you can use removeprefix:

'Path=helloworld'.removeprefix('Path=')
# 'helloworld'

回答 1

如果字符串是固定的,则可以简单地使用:

if line.startswith("Path="):
    return line[5:]

它将为您提供字符串中从位置5开始的所有内容(字符串也是一个序列,因此这些序列运算符也可以在此处使用)。

或者,您可以先分割行=

if "=" in line:
    param, value = line.split("=",1)

然后,param是“ Path”,值是第一个=之后的其余值。

If the string is fixed you can simply use:

if line.startswith("Path="):
    return line[5:]

which gives you everything from position 5 on in the string (a string is also a sequence so these sequence operators work here, too).

Or you can split the line at the first =:

if "=" in line:
    param, value = line.split("=",1)

Then param is “Path” and value is the rest after the first =.


回答 2

从字符串中删除前缀

# ...
if line.startswith(prefix):
   return line[len(prefix):]

在第一次出现分隔符时通过 str.partition()

def findvar(filename, varname="Path", sep="=") :
    for line in open(filename):
        if line.startswith(varname + sep):
           head, sep_, tail = line.partition(sep) # instead of `str.split()`
           assert head == varname
           assert sep_ == sep
           return tail

使用ConfigParser解析类似INI的文件

from ConfigParser import SafeConfigParser
config = SafeConfigParser()
config.read(filename) # requires section headers to be present

path = config.get(section, 'path', raw=1) # case-insensitive, no interpolation

其他选择

Remove prefix from a string

# ...
if line.startswith(prefix):
   return line[len(prefix):]

Split on the first occurrence of the separator via str.partition()

def findvar(filename, varname="Path", sep="=") :
    for line in open(filename):
        if line.startswith(varname + sep):
           head, sep_, tail = line.partition(sep) # instead of `str.split()`
           assert head == varname
           assert sep_ == sep
           return tail

Parse INI-like file with ConfigParser

from ConfigParser import SafeConfigParser
config = SafeConfigParser()
config.read(filename) # requires section headers to be present

path = config.get(section, 'path', raw=1) # case-insensitive, no interpolation

Other options


回答 3

def remove_prefix(text, prefix):
    return text[len(prefix):] if text.startswith(prefix) else text
def remove_prefix(text, prefix):
    return text[len(prefix):] if text.startswith(prefix) else text

回答 4

一般来说,对于切片(有条件的或无条件的),我更喜欢同事最近提出的建议;使用带有空字符串的替换。更容易阅读代码,更少的代码(有时),以及减少指定错误字符数的风险。好; 我不使用Python,但在其他语言中,我更喜欢这种方法:

rightmost = full_path.replace('Path=', '', 1)

或-跟进该帖子的第一条评论–仅当行开头为时才应这样做Path

rightmost = re.compile('^Path=').sub('', full_path)

与上面建议的一些建议的主要区别在于,不涉及“幻数”(5),也不需要同时指定“ 5字符串“ Path=”,换句话说,我更喜欢代码维护中的这种方法。观点看法。

For slicing (conditional or non-conditional) in general I prefer what a colleague suggested recently; Use replacement with an empty string. Easier to read the code, less code (sometimes) and less risk of specifying the wrong number of characters. Ok; I do not use Python, but in other languages I do prefer this approach:

rightmost = full_path.replace('Path=', '', 1)

or – to follow up to the first comment to this post – if this should only be done if the line starts with Path:

rightmost = re.compile('^Path=').sub('', full_path)

The main difference to some of what has been suggested above is that there is no “magic number” (5) involved, nor any need to specify both ‘5and the string ‘Path=‘, In other words I prefer this approach from a code maintenance point of view.


回答 5

我更喜欢pop索引[-1]

value = line.split("Path=", 1).pop()

value = line.split("Path=", 1)[1]
param, value = line.split("Path=", 1)

I prefer pop to indexing [-1]:

value = line.split("Path=", 1).pop()

to

value = line.split("Path=", 1)[1]
param, value = line.split("Path=", 1)

回答 6

还是为什么不

if line.startswith(prefix):
    return line.replace(prefix, '', 1)

Or why not

if line.startswith(prefix):
    return line.replace(prefix, '', 1)

回答 7

怎么样..

>>> line = r'path=c:\path'
>>> line.partition('path=')
('', 'path=', 'c:\\path')

这个三元组是头部,分隔符和尾部

How about..

>>> line = r'path=c:\path'
>>> line.partition('path=')
('', 'path=', 'c:\\path')

This triplet is the head, separator, and tail.


回答 8

我能想到的最简单的方法是切片:

def find_path(i_file): 
    lines = open(i_file).readlines() 
    for line in lines: 
        if line.startswith("Path=") : 
            return line[5:]

快速了解切片符号,它使用两个索引而不是通常的索引。第一个索引指示要包含在切片中的序列的第一个元素,最后一个索引是要包含在切片中的最后一个元素之后的索引。
例如:

sequence_obj[first_index:last_index]

切片由所有的元素first_indexlast_index,包括first_index和不last_index。如果省略第一个索引,则默认为序列的开始。如果省略了最后一个索引,则它包括序列中最后一个元素之前的所有元素。也可以使用负索引。使用Google了解有关该主题的更多信息。

The simplest way I can think of is with slicing:

def find_path(i_file): 
    lines = open(i_file).readlines() 
    for line in lines: 
        if line.startswith("Path=") : 
            return line[5:]

A quick note on slice notation, it uses two indices instead of the usual one. The first index indicates the first element of the sequence you want to include in the slice and the last index is the index immediately after the last element you wish to include in the slice.
Eg:

sequence_obj[first_index:last_index]

The slice consists of all the elements between first_index and last_index, including first_index and not last_index. If the first index is omitted, it defaults to the start of the sequence. If the last index is omitted, it includes all elements up to the last element in the sequence. Negative indices are also allowed. Use Google to learn more about the topic.


回答 9

>>> import re

>>> p = re.compile(r'path=(.*)', re.IGNORECASE)

>>> path = "path=c:\path"

>>> re.match(p, path).group(1)
'c:\\path'
>>> import re

>>> p = re.compile(r'path=(.*)', re.IGNORECASE)

>>> path = "path=c:\path"

>>> re.match(p, path).group(1)
'c:\\path'

回答 10

在此未提及的另一个简单的单线:

value = line.split("Path=", 1)[-1]

这对于各种边缘情况也将正常工作:

>>> print("prefixfoobar".split("foo", 1)[-1])
"bar"

>>> print("foofoobar".split("foo", 1)[-1])
"foobar"

>>> print("foobar".split("foo", 1)[-1])
"bar"

>>> print("bar".split("foo", 1)[-1])
"bar"

>>> print("".split("foo", 1)[-1])
""

Another simple one-liner that hasn’t been mentioned here:

value = line.split("Path=", 1)[-1]

This will also work properly for various edge cases:

>>> print("prefixfoobar".split("foo", 1)[-1])
"bar"

>>> print("foofoobar".split("foo", 1)[-1])
"foobar"

>>> print("foobar".split("foo", 1)[-1])
"bar"

>>> print("bar".split("foo", 1)[-1])
"bar"

>>> print("".split("foo", 1)[-1])
""

回答 11

line[5:]

给您前五个字符之后的字符。

line[5:]

gives you characters after the first five.


回答 12

line[5:]将给出您想要的子字符串。搜索介绍并查找“切片符号”

line[5:] will give the substring you want. Search the introduction and look for ‘slice notation’


回答 13

如果您知道列表理解:

lines = [line[5:] for line in file.readlines() if line[:5] == "Path="]

If you know list comprehensions:

lines = [line[5:] for line in file.readlines() if line[:5] == "Path="]

回答 14

流行版本不太正确。我想你要:

>>> print('foofoobar'.split('foo', 1).pop())
foobar

The pop version wasn’t quite right. I think you want:

>>> print('foofoobar'.split('foo', 1).pop())
foobar

回答 15

为什么不使用带有转义符的正则表达式? ^匹配行的起始部分并re.MULTILINE在每行上匹配。re.escape确保匹配正确。

>>> print(re.sub('^' + re.escape('path='), repl='', string='path=c:\path\nd:\path2', flags=re.MULTILINE))
c:\path
d:\path2

Why not using regex with escape? ^ matches the initial part of a line and re.MULTILINE matches on each line. re.escape ensures that the matching is exact.

>>> print(re.sub('^' + re.escape('path='), repl='', string='path=c:\path\nd:\path2', flags=re.MULTILINE))
c:\path
d:\path2

回答 16

尝试以下代码

if line.startswith("Path="): return line[5:]

Try Following code

if line.startswith("Path="): return line[5:]

回答 17

我想这正是您要寻找的

    def findPath(i_file) :
        lines = open( i_file ).readlines()
        for line in lines :
            if line.startswith( "Path=" ):
                output_line=line[(line.find("Path=")+len("Path=")):]
                return output_line

I guess this what you are exactly looking for

    def findPath(i_file) :
        lines = open( i_file ).readlines()
        for line in lines :
            if line.startswith( "Path=" ):
                output_line=line[(line.find("Path=")+len("Path=")):]
                return output_line

回答 18

无需编写函数,此操作将根据列表进行拆分,在这种情况下为’Mr. | Dr. | Mrs。’,使用[1]进行拆分后选择所有内容,然后再次拆分并获取任何元素。在以下情况下,将返回“ Morris”。

re.split('Mr.|Dr.|Mrs.', 'Mr. Morgan Morris')[1].split()[1]

without having a to write a function, this will split according to list, in this case ‘Mr.|Dr.|Mrs.’, select everything after split with [1], then split again and grab whatever element. In the case below, ‘Morris’ is returned.

re.split('Mr.|Dr.|Mrs.', 'Mr. Morgan Morris')[1].split()[1]

回答 19

这在技术上与其他答案非常相似,但是没有重复的字符串操作,能够分辨前缀是否存在,并且仍然可读性强:

parts = the_string.split(prefix_to_remove, 1):
    if len(parts) == 2:
        #  do things with parts[1]
        pass

This is very similar in technique to other answers, but with no repeated string operations, ability to tell if the prefix was there or not, and still quite readable:

parts = the_string.split(prefix_to_remove, 1):
    if len(parts) == 2:
        #  do things with parts[1]
        pass

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。