如何将整数变量替换为搜索模式的一部分

时间:2019-05-09 16:56:50

标签: python regex python-3.x

我试图用我构建的列表内容替换文件中的一些占位符文本。我逐步浏览列表,随手算数,然后进行搜索,具体取决于计数。该计数是一个整数,是我在每个循环中使用的搜索词的一部分。

我无法为自己的生活弄清楚发生了什么事。我已经打印了所有可以想到的内容,看起来就像搜索字词匹配一样。我尝试了多种替换方法,但是坚持使用简单的替换示例来显示。

从文件中采样文本,将其加载到变量'filedata'中:

<core:para>ANSWER_1</core:para><core:para>2. Bilateral investment treaties</core:para><core:para>ANSWER_2</core:para><core:para>3. Domestic arbitration law</core:para><p>ANSWER_3</p><core:para>4. Domestic arbitration and UNCITRAL</core:para><core:para>ANSWER_4</core:para><core:para>5. Mandatory provisions</core:para><core:para>ANSWER_5</core:para><core:para>6. Substantive law</core:para><core:para>ANSWER_6</core:para><core:para>7. Arbitral institutions</core:para><core:para>ANSWER_7</core:para><core:para>8. Arbitrability</core:para><core:para>ANSWER_8</core:para><core:para>9. Requirements</core:para><core:para>ANSWER_9</core:para><core:para>10. Enforceability</core:para><core:para>ANSWER_10</core:para>

代码:

x = 1            
answerlist = ['Oranges', 'Apples', 'Mangos', 'Cherries']

for a in answerlist:
    searchterm = '<core:para>ANSWER_' + str(x) +'</core:para>'
    newdata = filedata.replace(searchterm, a)
    x=x+1

出于示例的目的,我已经对上面的answerlist变量进行了硬编码,但这是在更大的循环中动态创建的。

预期结果是:

<core:para>Oranges</core:para><core:para>2. Bilateral investment treaties</core:para><core:para>Apples</core:para>

实际结果是:

<core:para>ANSWER_1</core:para><core:para>2. Bilateral investment treaties</core:para><core:para>ANSWER_2</core:para>

我已经测试了x的任意一侧的模式,并且效果很好,所以问题似乎出在x上,某种程度上没有转换为我认为是的字符串。

任何想法可能是什么问题?

3 个答案:

答案 0 :(得分:1)

这是有效的方法,看起来好像是结束标记中的反斜杠。

x = 1            
answerlist = ['Oranges', 'Apples', 'Mangos', 'Cherries']

for a in answerlist:
    searchterm = '<core:para>ANSWER_' + str(x) + r'</core:para>'
    newdata = filedata.replace(searchterm, a)
    x=x+1

请注意searchterm变量构造中模式的最后一个字符串之前的r,它将字符串变成原始字符,无需转义字符。

答案 1 :(得分:0)

我将猜测您要在这里做什么。我已经从上面获取了示例文本,并在下面的代码中将其分配给字符串txt。我可以将re.splitgroupings(括号中的内容)一起使用,以获取要创建列表的编号。然后,我可以遍历列表中的所有其他元素,取出我感兴趣的整数,然后将列表中的该值重新分配给我的替换对象。在这种情况下,我只是根据大写字母替换,但是您可以在此处放置任何想要的列表

txt="""<core:para>ANSWER_4</core:para><core:para>5. Mandatory provisions</core:para><core:para>ANSWER_5</core:para><core:para>6. Substantive law</core:para><core:para>ANSWER_6</core:para><core:para>7. Arbitral institutions</core:para><core:para>ANSWER_7</core:para><core:para>8. Arbitrability</core:para><core:para>ANSWER_8</core:para><core:para>9. Requirements</core:para><core:para>ANSWER_9</core:para><core:para>10. Enforceability</core:para><core:para>ANSWER_10</core:para><core:para>11. Third parties - bound by arbitration agreement</core:para><core:para>ANSWER_11</core:para><core:para>12. Third parties - participation</core:para><core:para>ANSWER_12</core:para><core:para>13. Groups of companies</core:para><core:para>ANSWER_13</core:para><core:para>14. Multiparty arbitration agreements</core:para><core:para>ANSWER_14</core:para><core:para>15. Eligibility of arbitrators</core:para><core:para>ANSWER_15</core:para><core:para>16. Background of arbitrators</core:para><core:para>ANSWER_16</core:para>"""
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
pieces = re.split(r'<core:para>ANSWER_([0-9]+)</core:para>', txt)
for i in range(1, len(pieces), 2):
    idx = int(pieces[i])
    pieces[i] = f'A CAPITAL LETTER: {alphabet[idx]}'
print(''.join(pieces))

这将打印出来:

大写字母:E5。强制性规定大写字母:F6。实体法首字母大写:G7。仲裁机构首字母:H8。可仲裁性大写字母:I9。要求大写字母:J10。可执行性大写字母:K11。第三方-受仲裁协议的约束大写字母:L12。第三方-参与大写字母:M13。公司集团大写字母:N14。多方仲裁协议大写字母:O15。仲裁员的资格大写字母:P16。仲裁员的背景大写字母:Q

答案 2 :(得分:0)

您可能需要先捕获它们,然后使用简单的for循环和字符串替换将其替换为所需的数字。

This expression可能会帮助您使用捕获组([0-9]+)来捕获所需的号码:

(<core:para>ANSWER_)([0-9]+)(<\/core:para>)

enter image description here

使用Python测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(<core:para>ANSWER_)([0-9]+)(<\/core:para>)"

test_str = "<core:para>ANSWER_4</core:para><core:para>5. Mandatory provisions</core:para><core:para>ANSWER_5</core:para><core:para>6. Substantive law</core:para><core:para>ANSWER_6</core:para><core:para>7. Arbitral institutions</core:para><core:para>ANSWER_7</core:para><core:para>8. Arbitrability</core:para><core:para>ANSWER_8</core:para><core:para>9. Requirements</core:para><core:para>ANSWER_9</core:para><core:para>10. Enforceability</core:para><core:para>ANSWER_10</core:para><core:para>11. Third parties - bound by arbitration agreement</core:para><core:para>ANSWER_11</core:para><core:para>12. Third parties - participation</core:para><core:para>ANSWER_12</core:para><core:para>13. Groups of companies</core:para><core:para>ANSWER_13</core:para><core:para>14. Multiparty arbitration agreements</core:para><core:para>ANSWER_14</core:para><core:para>15. Eligibility of arbitrators</core:para><core:para>ANSWER_15</core:para><core:para>16. Background of arbitrators</core:para><core:para>ANSWER_16</core:para>"

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

使用JavaScript测试

const regex = /(<core:para>ANSWER_)([0-9]+)(<\/core:para>)/gm;
const str = `<core:para>ANSWER_4</core:para><core:para>5. Mandatory provisions</core:para><core:para>ANSWER_5</core:para><core:para>6. Substantive law</core:para><core:para>ANSWER_6</core:para><core:para>7. Arbitral institutions</core:para><core:para>ANSWER_7</core:para><core:para>8. Arbitrability</core:para><core:para>ANSWER_8</core:para><core:para>9. Requirements</core:para><core:para>ANSWER_9</core:para><core:para>10. Enforceability</core:para><core:para>ANSWER_10</core:para><core:para>11. Third parties - bound by arbitration agreement</core:para><core:para>ANSWER_11</core:para><core:para>12. Third parties - participation</core:para><core:para>ANSWER_12</core:para><core:para>13. Groups of companies</core:para><core:para>ANSWER_13</core:para><core:para>14. Multiparty arbitration agreements</core:para><core:para>ANSWER_14</core:para><core:para>15. Eligibility of arbitrators</core:para><core:para>ANSWER_15</core:para><core:para>16. Background of arbitrators</core:para><core:para>ANSWER_16</core:para>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

此图显示了表达式的工作方式,您可以在此link中可视化其他表达式:

enter image description here

性能测试

此JavaScript代码段使用简单的100万次for循环来显示该表达式的性能。

const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const string = '<core:para>ANSWER_4</core:para>';
	const regex = /(<core:para>ANSWER_)([0-9]+)(<\/core:para>)/gm;
	var match = string.replace(regex, "$2");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");