我有一个以下文本文件,将以某种方式进行编辑。文件中位于(init:部分)内部的部分将被覆盖,除了应编辑的部分外,其他所有内容都不能编辑。
文件:
(define (problem bin-picking-doosra)
(:domain bin-picking-second)
;(:requirements :typing :negative-preconditions)
(:objects
)
(:init
(batsmen first_batsman)
(bowler none_bowler)
(umpire third_umpire)
(spectator no_spectator)
)
(:goal (and
(batsmen first_batsman)
(bowler last_bowler)
(umpire third_umpire)
(spectator full_spectator)
)
)
)
在此文件中,我想用必需的字符串替换(init:部分”中的每一行。在这种情况下,我想替换:
(batsmen first_batsman)与(batsmen none_batsmen)
(保龄球none_bowler)和(保龄球first_bowler)
(裁判第三人)和(裁判leg_umpire)
(spectator no_spectator)与(spectator empty_spectator)
我当前拥有以下代码:
file_path = "/home/mus/problem_turtlebot.pddl"
s = open(file_path).read()
s = s.replace('(batsmen first_batsman)', '(batsmen '+ predicate_batsmen + '_batsman)')
f = open(file_path, 'w')
f.write(s)
f.close()
此处的 predicate_batsmen 一词包含 none 一词。这样可以很好地工作。该代码仅满足上述第1点。
我有三个问题。
此代码还更改了我不想要的(目标:部分中的(batsmen first_batsmen)'部分。我只希望它更改(init:部分
当前,对于(init:部分中的其他字符串,我必须使用不同的语句重做此代码。例如:对于'(bowler none_bowler)',即上述第2点,我必须再次获得编码行的副本,我认为这不是一种好的编码技术,任何更好的方法。
如果我们认为(init:)中的第一个字符串将被覆盖,即(batsmen first_batsman)。python中是否有一种方法,无论用什么方式写像(batsmen ?????? _ batsman)这样的字符串中的问号部分可以用 none 代替。现在,它是'first',即使已写'second'((batsmen second_batsman))或'last'((batsmen last_batsman)),我想将其替换为'none' (击球手none_batsman)。
关于这些问题有什么想法吗?
谢谢
答案 0 :(得分:1)
首先,您需要找到init
组。 init
组似乎具有以下结构:
(:init
...
)
其中...
是括号内包含的文本的重复出现,例如"(batsmen first_batsman)"
。正则表达式是在文本中定位此类模式的有效方法。如果您不熟悉正则表达式(或简称regex),请看看here。
以下正则表达式可找到该组:
import re
#Matches the items in the init-group:
item_regex = r"\([\w ]+\)\s+"
#Matches the init-group including items:
init_group_regex = re.compile(r"(\(:init\s+({})+\))".format(item_regex))
init_group = init_group_regex.search(s).group()
现在,您在init
中拥有match
组。下一步是找到要替换的术语,然后实际替换它。 re.sub
可以做到!首先将映射存储在字典中:
mappings = {'batsmen first_batsman': 'batsmen '+ predicate_batsmen + '_batsman',
'bowler none_bowler': 'bowler first_bowler',
'umpire third_umpire': 'umpire leg_umpire',
'spectator no_spectator': 'spectator empty_spectator'}
查找事件并用它们对应的值一个一替换:
for key, val in mappings.items():
init_group = re.sub(key, val, init_group)
最后,您可以替换原始字符串中的init
组:
s = init_group_regex.sub(init_group, s)
这真的很灵活!您可以在mappings
中使用正则表达式使其与您喜欢的任何内容匹配,包括:
mappings = {'batsmen \w+_batsman': '(batsmen '+ predicate_batsmen + '_batsman)'}
匹配'batsmen none_batsman'
,'batsmen first_batsman'
等