我正在尝试使用python中的re.split解析一行。以下是我正在尝试的示例行:
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName_1
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName 1
我使用以下代码将每一行拆分成一个数组,并使用最后一个元素。
file_folder_names_parsed.insert(file_index, (re.split(r"\s", entry)))
print file_folder_names_parsed[file_index]
#The file/folder name is stored in the last element, lets index to that
num_elements_in_parsed_string = len(file_folder_names_parsed[file_index])
parsed_folder_names.insert(file_index, file_folder_names_parsed[file_index][num_elements_in_parsed_string-1])
现在的问题是,对于前两行,它工作正常,我能够使用以下条目填充列表:[FolderName,FolderName_1]
但是对于最后一个元素,我只得到[1]而不是[FolderName 1]。这是有道理的,因为中间有一个空格字符,我将其用作分隔符。不幸的是,我无法使用\ t(tab)作为我必须处理的字符串的正则表达式分隔符。
任何人都可以建议最后一个案例,我怎样才能获得[FolderName 1]而不是只获得[1]我目前得到的?
答案 0 :(得分:3)
可能是这样的吗?
>>> import re
>>> s = '''drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName_1
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName 1'''
>>> re.findall(r'(?<=:\d{2})\s+(.*)(?=\n|$)', s)
['FolderName', 'FolderName_1', 'FolderName 1']
正则表达式解释:http://regex101.com/r/fM1nM4/1
答案 1 :(得分:3)
您应该匹配非空的空格字符序列,如下所示:\s+
。此外,您应使用re.split()
&#39; s maxsplit
参数指定您愿意接受的最大分组数:
import re
lines = [
'drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName',
'drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName_1',
'drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName 1',
]
for entry in lines:
filename = re.split(r'\s+', entry, maxsplit=8)[-1]
print filename
在分割前8个项目后,re.split()
会将该行的剩余部分作为单个项目返回。
但是,如果您只是使用whitepsace作为分隔符,那么根本不需要re.split()
。只需使用更简单的str.split()
:
for entry in lines:
filename = entry.split(None, 8)[-1]
print filename
上述任何一个样本都会产生此输出:
FolderName
FolderName_1
FolderName 1
答案 2 :(得分:2)
根据没有数字和行尾锚点的空格分开,
>>> m = re.split(r'(?<!:\d{2} \d)\s+(?!\d+$)', 'drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName 1')
>>> m
['drwxr-xr-x', '2', 'user1', 'user1', '4096', 'Sep', '4', '14:23', 'FolderName 1']
>>> m = re.split(r'(?<!:\d{2} \d)\s+(?!\d+$)', 'drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 1 FolderName')
>>> m
['drwxr-xr-x', '2', 'user1', 'user1', '4096', 'Sep', '4', '14:23', '1 FolderName']
模式说明:
(?<!:\d{2} \d)\s+(?!\d+$)
(?<!....)
称为负向后观,它断言空格之前的内容不满足此:\d{2} \d
模式。 (?!\d+$)
称为负向前瞻,断言,后面不是一个或多个数字和行尾$
答案 3 :(得分:2)
不使用split()
,使用实际模式。
import re
listing = """drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName_1
drwxr-xr-x 2 user1 user1 4096 Sep 4 14:23 FolderName 1
asdasd
"""
listing_pattern = r"\s+".join([
r"^(?P<type>\S)(?P<mode>\S+)",
r"(?P<children>\d+)",
r"(?P<user>\S+)",
r"(?P<group>\S+)",
r"(?P<size>\S+)",
r"(?P<time>.*\d:\d\d)",
r"(?P<filename>.*)",
])
for entry in iter(listing.splitlines()):
match = re.match(listing_pattern, entry)
if match:
print match.group("filename")
打印
FolderName FolderName_1 FolderName 1
正如@tripleee在评论中指出的那样,你不应该首先解析ls
的输出。在上面,链接中最弱的链是<time>
组(想想上午/下午时间表示)。
如果您对文件名之前的列不感兴趣,那么较短的正则表达式就足够了:
listing_pattern = r".*?:\d\d (?P<filename>.*)"
同样,时间以":"
后跟两位数结尾的假设是该方法的弱点。