2013-02-01 66 views
7

Tôi muốn so sánh hai tài liệu bất kể ngắt dòng. Nếu nội dung giống nhau nhưng vị trí và số lượng ngắt dòng khác nhau, tôi muốn ánh xạ các dòng trong một tài liệu tới các dòng trong phần còn lại.So sánh hai tài liệu bằng cách sử dụng regex

Given:

Document 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. 

Document 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. 

Tôi muốn một thuật toán có khả năng xác định rằng dòng 1 tại văn bản 1 chứa nội dung giống với dòng từ 1 đến 5 trong Tài liệu 2, các dòng 2 và 3 trong Tài liệu 1 chứa cùng văn bản như dòng 6 trong Tài liệu 2, v.v.

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

Có cách nào để regex khớp với mỗi dòng trong mỗi tài liệu nếu nó trải rộng trên nhiều dòng trong các tài liệu khác không?

+0

Các số đó là gì? –

+0

Một cách tiếp cận sẽ là chỉ tách cả hai đầu vào thành các từ, duy trì các dòng mà chúng xuất phát và chỉ tương ứng với từng từ một (giả sử các từ giống nhau). – nneonneo

+0

các dòng phù hợp với từng tài liệu – hmghaly

Trả lời

0

Bạn có thể lặp qua từng dòng doc1 và làm điều gì đó như thế này:

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

Sau đó thực hiện tìm kiếm trên doc2 sử dụng chuỗi tìm kiếm này.

match = re.search(searchstring, contents)

Nếu matchNULL, sau đó là không phù hợp. khác, match.group(0) sẽ cung cấp cho bạn những nội dung phù hợp với các doc 2.

'I went\nto Paris\nin July 15,\nwhere I met\nsome nice people.'

Sau đó, nó là một bài tập đơn giản của tách rằng bằng '\ n' và tìm hiểu các dòng trong doc2 họ đến từ đâu.

2

Tôi không phải là một lập trình viên python, nhưng điều này không giống như một vấn đề có thể được giải quyết bằng regex.

Thay vào đó, trước tiên bạn muốn so sánh tài liệu để đảm bảo nội dung giống nhau (tạm thời xóa tất cả các dòng mới). Tôi không biết những gì bạn muốn làm nếu nó không phải là, vì vậy tôi sẽ không giải quyết điều đó.

Tạo bộ sưu tập các bộ sưu tập số nguyên được gọi là linemappings

Bắt đầu vòng lặp. Vòng lặp sẽ đi qua từng ký tự trong mỗi tài liệu cùng một lúc. Bạn sẽ cần bốn biến truy cập. charindex1 sẽ chứa các chỉ số ký tự hiện tại văn bản 1 và charindex2 sẽ chứa các chỉ số charater hiện tại văn bản 2. lineindex1 sẽ chứa các chỉ số dòng hiện tại văn bản 1 và lineindex2 sẽ chứa các chỉ số dòng hiện tại văn bản 2.

Bắt đầu với các biến chỉ mục char thành 0 và các biến chỉ mục dòng được khởi tạo thành 1.

Bắt đầu Loop:

Lấy ký tự hiện từ mỗi tài liệu: char1 từ tài liệu 1 và char2 từ tài liệu 2.

Nếu char1char2 là cả hai dòng mới hoặc CẢ là dòng mới, sau đó tạm ứng cả hai charindex1charindex2 theo 1.
Khác Nếu char1 là dòng mới, sau đó tiến hành charindex1 bằng 1.
Else Nếu char2 là một dòng mới, sau đó tiến charindex2 bởi 1.

nếu một trong hai char1 hoặc char2 là một dòng mới, sau đó chèn một kỷ lục mới vào bộ sưu tập linemappings (kết quả cuối cùng sẽ là một cái gì đó như [[1,1],[1,2],[1,3],[1,4],[1,5],[2,6],[3,6],[4,7],[5,7],[6,7],[6,8])

Nếu char1 là một dòng mới, thúc đẩy lineindex1 bởi 1.
Nếu char2 là một dòng mới, thúc đẩy lineindex2 bởi 1.

Lặp lại cho đến khi kết thúc đầu vào.

(Tôi thực sự không thể kiểm tra điều này vì tôi không phải là một lập trình viên python, nhưng hy vọng bạn sẽ có được các ý chính và có thể sửa đổi nó để phù hợp với nhu cầu của bạn.)

+0

@TerryLi có câu trả lời hay hơn. Tôi muốn đi với điều đó, cá nhân. – JDB

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++; 
       } 
      } 
     } 
    } 
} 

Mẫu đầu ra:

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

Mã Java hoàn chỉnh và đang hoạt động. Nó không phải là một giải pháp regex, vì vậy nó có thể không phù hợp với nhu cầu của bạn.

Ý tưởng là chúng tôi tạo một mảng cho mỗi tài liệu. Kích thước của mảng bằng với số dòng trong mỗi tài liệu. Phần tử thứ n của mảng lưu trữ số từ được nhìn thấy lên dòng thứ n của tài liệu. Sau đó, chúng tôi xác định các phần tử bằng nhau trong cả hai mảng, có chỉ số xác định phạm vi của đầu ra.