使用正则表达式比较两个文档

7
我想比较两个文档,而不考虑换行符。如果内容相同但换行符的位置和数量不同,则希望将一个文档中的行映射到另一个文档中的行。
给定:
文档 1
I went to Paris in July 15, where I met some nice people.
And I came back
to NY in Aug 15.
I am planning
to go there soon
after I finish what I do.

文档2

I went
to Paris
in July 15,
where I met
some nice people.
And I came back to NY in Aug 15.
I am planning to go
there soon after I finish what I do.

我希望有一种算法,能够确定文档1中的第1行包含与文档2中第1至第5行相同的文本,文档1中的第2行和第3行包含与文档2中的第6行相同的文本,以此类推。

1 = 1,2,3,4,5
2,3 = 6
4,5,6 = 7,8

是否有一种正则表达式的方法,可以在其他文档中跨越多行的情况下匹配每个文档中的每一行?

一种方法是将两个输入都分割成单词,保留它们来自的行,然后逐个对应这些单词(假设这些单词是相同的)。 - nneonneo
I'm sorry, but you did not provide any documents or texts to be translated. Please provide the content that needs to be translated. - hmghaly
我试图澄清你问题的意图。如果我理解有误,你可以使用编辑器“回滚”到以前的版本。 - JDB
谢谢@Cyborgx37,也许我需要更多的澄清,我认为你的尝试是不错的。 - hmghaly
更新:问题在于尝试匹配跨越多行的每一行:pattern='我在7月15日去了巴黎,在那里遇到了一些好人。' pat=re.compile(pattern,re.MULTILINE) matching=[v.span() for v in pat.finditer(doc2_text)] 不知何故,多行匹配似乎无法正常工作。 - hmghaly
显示剩余3条评论
3个回答

3
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.commons.io.FileUtils;

public class Compare {
    public static void main(String[] args) throws IOException {
        String doc1 = FileUtils.readFileToString(new File("Doc1.txt"));
        String doc2 = FileUtils.readFileToString(new File("Doc2.txt"));
        String[] array1 = doc1.split("\n");
        String[] array2 = doc2.split("\n");
        int[] count1 = new int[array1.length];
        int[] count2 = new int[array2.length];
        int sum1 = 0;
        int sum2 = 0;
        for (int i=0;i<count1.length;i++) {
            count1[i] = sum1 + array1[i].split(" ").length;
            sum1 = count1[i];
        }
        for (int i=0;i<count2.length;i++) {
            count2[i] = sum2 + array2[i].split(" ").length;
            sum2 = count2[i];
        }
        ArrayList<Integer> result1 = new ArrayList<Integer>();
        ArrayList<Integer> result2 = new ArrayList<Integer>();
        for (int j=0; j<count1.length; ) {
            for (int k=0; k<count2.length; ) {
                if (count1[j]==count2[k]) {
                    result1.add(j+1);
                    result2.add(k+1);
                    System.out.println(result1.toString()+" = "+result2.toString());
                    result1 = new ArrayList<Integer>();
                    result2 = new ArrayList<Integer>();
                    j++;k++;
                } else if (count1[j]>count2[k]) {
                    result2.add(k+1);
                    k++;
                } else {
                    result1.add(j+1);
                    j++;
                }
            }
        }
    }
}

样例输出:

[1] = [1, 2, 3, 4, 5]
[2, 3] = [6]
[4, 5, 6] = [7, 8]

完整可用的Java代码。它不是正则表达式解决方案,所以可能不适合您的需求。

我们的想法是为每个文档创建一个数组。数组的大小等于每个文档中的行数。数组的第n个元素存储到文档的第n行为止看到的单词数。然后我们在两个数组中识别相等的元素,其索引定义了输出的范围。


2
我不是Python程序员,但这个问题似乎不能用正则表达式解决。相反,您首先需要比较文档以确保内容相同(暂时删除所有换行符)。如果不相同,我不知道您想做什么,所以我不会去处理它。
创建一个名为linemappings的整数集合
开始循环。循环将同时遍历每个文档的每个字符。你需要四个计数器变量。charindex1将包含文档1中的当前字符索引,charindex2将包含文档2中的当前字符索引。lineindex1将包含文档1中的当前行索引,而lineindex2将包含文档2中的当前行索引。
将char索引变量设置为0,将line索引变量初始化为1。
开始循环: 获取每个文档的当前字符:从文档1获取char1和从文档2获取char2。 如果char1和char2都是换行符或都不是换行符,则将charindex1和charindex2同时增加1。 否则,如果char1是换行符,则将charindex1增加1。 否则,如果char2是换行符,则将charindex2增加1。 如果char1或char2中的任意一个是换行符,则在linemappings集合中插入一个新记录(最终结果将类似于[[1,1],[1,2],[1,3],[1,4],[1,5],[2,6],[3,6],[4,7],[5,7],[6,7],[6,8]])。 如果char1是换行符,则将lineindex1增加1。如果char2是换行符,则将lineindex2增加1。
直到达到输入的结尾为止。(我无法真正测试它,因为我不是Python程序员,但希望您能理解并修改以适应您的需要。)

@TerryLi的回答更好。个人而言,我会选择那个。 - JDB

0

您可以遍历doc1的每一行,然后像这样进行操作:

searchstring = line.replace(' ', '[ |\n]')

然后使用此搜索字符串在doc2上进行搜索。

match = re.search(searchstring, contents)

如果matchNULL,则没有匹配。否则,match.group(0)将为您提供doc 2中匹配的内容。

'我在7月15日去了巴黎,在那里遇见了一些好人。'

然后,只需通过'\\ n'进行分割,并确定它们来自doc2中的哪些行即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接