简体   繁体   English

python替换文件行中的多个模式

[英]python replace multiple patterns in the lines of a file

Here is a problem which is annoying me during these last two hours. 这是一个让我在过去两个小时内烦恼的问题。 I have a template file with multiple lines and in some lines some words have to be changed by some others. 我有一个包含多行的模板文件,在某些行中,某些单词必须由其他一些单词更改。 Here is how my template looks like: 以下是我的模板的样子:

subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }} {}

subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }}
{
option domain-name-servers {{ MY_DOMAIN_IP }}; 
option domain-name {{ MY_DOMAIN_NAME }}; 
option routers {{ MY_GATEWAY }}; 
option broadcast-address {{ MY_BROADCAST }};

Here is the code I am using: 这是我正在使用的代码:

f = open(DHCPD_PATH, 'w')
g = open(TEMPLATE_PATH, 'r')
patterns = { 
   '{{ MAC_ADDRESS }}'     : mac,
   '{{ IP_ADDRESS }}'      : ip, 
   '{{ MY_IP }}'           : MY_IP,
   '{{ MY_DOMAIN_IP }}'    : MY_DOMAIN_IP,
   '{{ MY_DOMAIN_NAME }}'  : MY_DOMAIN_NAME,
   '{{ MY_NETMASK }}'      : MY_NETMASK,
   '{{ MY_GATEWAY }}'      : MY_GATEWAY,
   '{{ MY_SUBNET }}'       : MY_SUBNET,
   '{{ MY_BROADCAST }}'    : MY_BROADCAST,
}   
content = g.read()
for i,j in patterns.iteritems():
   content = content.replace(i,j)
f.write(content)
f.close()
g.close()

Here is the file I get: 这是我得到的文件:

subnet 192.168.10.0 netmask {{ MY_NETMASK }} {}

subnet 192.168.10.0 netmask 255.255.255.0
{
  option domain-name-servers 192.168.10.10;
  option domain-name "localnet.lan";
  option routers 192.168.10.1;
  option broadcast-address 192.168.10.255;
  default-lease-time 600;
  max-lease-time 7200;
  filename "pxelinux.0";
  next-server 192.168.10.3;

I can't understand why is this {{ MY_NETMASK }} remaining whereas one of it has been correctly replaced and every others template-patterns get also correctly replaced. 我无法理解为什么这个{{MY_NETMASK}}仍然存在,而其中一个已被正确替换,其他模板模式也被正确替换。

Can anyone give me a hint on this one? 任何人都可以给我一个暗示吗? Or at least explain me how to correct it? 或者至少解释一下如何纠正它?

Many thanks 非常感谢

@eumiro guessed right: one of your spaces isn't a space. @eumiro猜对了:你的一个空间不是空间。

>>> repr('subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }} {}')
"'subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK\\xc2\\xa0}} {}'"
                                              ^^^^^^^^^^

Looks like a non-breaking space. 看起来像一个不间断的空间。

Thank you SO much!! 太感谢你

To provide a more complete answer (although yours were clear enough to solve my problem) I would like to provide the vim configuration which would have spared my the pain: 为了提供一个更完整的答案(虽然你的答案非常明确,可以解决我的问题),我想提供一个可以避免痛苦的vim配置:

provides different colors for spaces and tabulations: 为空格和表格提供不同的颜色:

:set syntax=whitespace

This line in the ~/.vimrc configuration file prints most of invisible characters if you use the :list command once your file is opened (:list! to go back to normal view): 如果在打开文件后使用:list命令,则〜/ .vimrc配置文件中的这一行打印大部分不可见字符(:list!返回普通视图):

set listchars=nbsp:¤,tab:>-,trail:¤,extends:>,precedes:<,eol:¶,trail:· 

Thanks again 再次感谢

Aside from 'iffy' characters that others have pointed out... 除了别人指出的'iffy'字符......

It may be overkill but - I would be tempted to just install the jinja2 templating library , give it TEMPLATE_PATH (either as a string, or as part of an environment or a file), then issue .render with your PATTERNS , which would become: 它可能有点矫枉过正 - 但是 - 我很想安装jinja2模板库 ,给它TEMPLATE_PATH (作为字符串,或作为环境或文件的一部分),然后用你的PATTERNS发出.render ,它将成为:

PATTERNS = {
    'MAC_ADDRESS': '121422242424',
    # etc...
}

The replacements will also be done all at once, rather than iteratively searched/replaced. 替换也将一次完成,而不是迭代搜索/替换。 You could also put in the template reasonable default values, ie: option something {{ MY_IP|default('127.0.0.1') }} 您还可以在模板中输入合理的默认值,即: option something {{ MY_IP|default('127.0.0.1') }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM