0

我正在尝试将频道名称替换为 AndroidManifest.xml 以批量生成一组频道 apk 包以供发布。

<meta-data android:value="CHANNEL_NAME_TO_BE_DETERMINED" android:name="UMENG_CHANNEL"/> 从一个 xml 文件。

频道配置保存在配置文件中,例如:

channel_name    output_postfix  valid 
"androidmarket" "androidmarket" true

这是我尝试过的:

manifest_original_xml_fh = open("../AndroidManifest_original.xml", "r")
manifest_xml_fh = open("../AndroidManifest.xml", "w")
pattern = re.compile('<meta-data\sandroid:value=\"(.*)\"\sandroid:name=\"UMENG_CHANNEL\".*')
for each_config_line in manifest_original_xml_fh:
    each_config_line = re.sub(pattern, channel_name, each_config_line) 
    print each_config_line

它取代了显然不是我需要<meta-data android:value="CHANNEL_NAME_TO_BE_DETERMINED" android:name="UMENG_CHANNEL"/>的整体。androidmarket然后我发现问题是pattern.match(each_config_line)返回匹配结果,结果组之一是“CHANNEL_NAME_TO_BE_DETERMINED”。我也尝试过提供一些替换实现功能,但仍然失败。

那么,既然我已经成功找到了模式,我该如何正确替换匹配的结果组元素呢?

4

3 回答 3

1

我建议另一种方法:将您的 xml 保存为模板,并用标准 Python 字符串操作替换占位符。

例如

AndroidManifest_template.xml:

<meta-data android:value="%(channel_name)s" android:name="UMENG_CHANNEL"/>

python:

manifest_original_xml_fh = open("../AndroidManifest_template.xml", "r")
manifest_xml_fh = open("../AndroidManifest.xml", "w")
for each_config_line in manifest_original_xml_fh:
    each_config_line = each_config_line % {'channel_name': channel_name}
    print each_config_line
于 2012-05-04T07:28:42.687 回答
0

要仅捕获元数据标记的值,您需要更改正则表达式:

<meta-data\sandroid:value=\"([^"]*)\"\sandroid:name=\"UMENG_CHANNEL\".*

具体来说,我改变了这部分:

\"(.*)\"- 这是一个贪婪匹配,所以只要表达式的其余部分匹配,它就会继续匹配尽可能多的字符

\"([^"]*)\"- 这将匹配任何不是双引号的东西。匹配结果仍将在第一个捕获组中

如果你想做替换的事情,一个更好的主意可能是捕捉你想要保持不变的东西——我不是 python 专家,但这样的事情可能会起作用:

re.sub(r'(<meta-data\sandroid:value=\")[^"]*(\"\sandroid:name=\"UMENG_CHANNEL\".*)'
, r'\1YourNewValue\2', s)

\1是反向引用 1 - 即它得到第一个捕获组匹配的内容

于 2012-05-04T07:15:20.940 回答
0

我认为你的误解是,所有匹配的都会被替换。如果您想保留模式中的内容,则必须捕获它并将其重新插入替换字符串中。

或使用环视断言仅匹配您要替换的内容

试试这个

pattern = re.compile('(?<=<meta-data\sandroid:value=\")[^"]+')
for each_config_line in manifest_original_xml_fh:
    each_config_line = re.sub(pattern, channel_name, each_config_line)

(?<=<meta-data\sandroid:value=\")是一个肯定的lookbehind断言,它确保这个文本是之前的,但不匹配它(所以它不会被替换)

[^"]+然后将匹配任何不是"

在 Regexr 上查看

于 2012-05-04T07:32:52.093 回答