Tôi ghét phân tích tệp, nhưng đó là điều tôi phải làm khi bắt đầu gần như mọi dự án. Phân tích cú pháp không dễ dàng và nó có thể là một trở ngại cho người mới bắt đầu. Tuy nhiên, một khi bạn đã thành thạo với việc phân tích tệp, bạn sẽ không bao giờ phải lo lắng về phần vấn đề đó nữa. Đó là lý do tại sao tôi khuyên những người mới bắt đầu nên làm quen với việc phân tích tệp sớm trong quá trình học lập trình của họ. Bài viết này dành cho những người mới bắt đầu sử dụng Python, những người quan tâm đến việc học phân tích cú pháp các tệp văn bản
Trong bài viết này, tôi sẽ giới thiệu với các bạn về hệ thống phân tích tệp của tôi. Tôi sẽ đề cập ngắn gọn về phân tích cú pháp các tệp ở định dạng tiêu chuẩn, nhưng điều tôi muốn tập trung vào là phân tích cú pháp các tệp văn bản phức tạp. Ý tôi là gì bởi sự phức tạp?
Để tham khảo, bản trình chiếu mà tôi sử dụng để trình bày về chủ đề này có tại đây. Tất cả mã và văn bản mẫu mà tôi sử dụng đều có sẵn trong repo Github của tôi tại đây
- Tại sao phân tích các tập tin?
- bức tranh lớn
- Phân tích cú pháp văn bản ở định dạng chuẩn
- Phân tích cú pháp văn bản bằng các phương thức chuỗi
- Phân tích cú pháp văn bản ở định dạng phức tạp bằng các biểu thức thông thường
- Bước 1. Hiểu định dạng đầu vào
- Bước 2. Nhập các gói cần thiết
- Bước 3. Định nghĩa biểu thức chính quy
- Bước 4. Viết trình phân tích cú pháp dòng
- Bước 5. Viết trình phân tích tệp
- Bước 6. Kiểm tra trình phân tích cú pháp
- Đây có phải là giải pháp tốt nhất?
- Phần kết luận
Đầu tiên, hãy để chúng tôi hiểu vấn đề là gì. Tại sao chúng ta thậm chí cần phải phân tích các tập tin? . Sẽ không cần phải phân tích các tập tin. Tuy nhiên, chúng ta đang sống trong một thế giới có rất nhiều định dạng dữ liệu. Một số định dạng dữ liệu phù hợp hơn với các ứng dụng khác nhau. Một chương trình riêng lẻ chỉ có thể phục vụ cho việc lựa chọn các định dạng dữ liệu này. Vì vậy, chắc chắn có nhu cầu chuyển đổi dữ liệu từ định dạng này sang định dạng khác để sử dụng bởi các chương trình khác nhau. Đôi khi dữ liệu thậm chí không ở định dạng chuẩn khiến mọi thứ khó hơn một chút
Vì vậy, phân tích cú pháp là gì?
Phân tích cú pháp [một chuỗi hoặc văn bản] thành các thành phần cú pháp logicTôi không thích định nghĩa từ điển Oxford ở trên. Vì vậy, đây là định nghĩa thay thế của tôi
ParseChuyển đổi dữ liệu ở một định dạng nhất định sang định dạng dễ sử dụng hơn. bức tranh lớnVới định nghĩa đó, chúng ta có thể tưởng tượng rằng đầu vào của chúng ta có thể ở bất kỳ định dạng nào. Vì vậy, bước đầu tiên, khi đối mặt với bất kỳ vấn đề phân tích cú pháp nào, là hiểu định dạng dữ liệu đầu vào. Nếu bạn may mắn, sẽ có tài liệu mô tả định dạng dữ liệu. Nếu không, bạn có thể phải tự giải mã định dạng dữ liệu. Đó luôn là niềm vui
Khi bạn hiểu dữ liệu đầu vào, bước tiếp theo là xác định định dạng nào sẽ hữu dụng hơn. Chà, điều này hoàn toàn phụ thuộc vào cách bạn định sử dụng dữ liệu. Nếu chương trình mà bạn muốn cung cấp dữ liệu vào yêu cầu định dạng CSV, thì đó là sản phẩm cuối cùng của bạn. Để phân tích dữ liệu sâu hơn, tôi thực sự khuyên bạn nên đọc dữ liệu vào một con gấu trúc
import pandas as pd
df = pd.read_csv['data.txt']
df
2Nếu bạn là nhà phân tích dữ liệu Python thì rất có thể bạn đã quen thuộc với pandas. Đó là gói Python cung cấp lớp
import pandas as pd
df = pd.read_csv['data.txt']
df
2 và các chức năng khác để thực hiện phân tích dữ liệu cực kỳ mạnh mẽ với nỗ lực tối thiểu. Nó là một sự trừu tượng hóa trên Numpy cung cấp các mảng đa chiều, tương tự như Matlab. import pandas as pd
df = pd.read_csv['data.txt']
df
2 là một mảng 2D, nhưng nó có thể có nhiều chỉ số hàng và cột, mà gấu trúc gọi là import pandas as pd
df = pd.read_csv['data.txt']
df
5, về cơ bản cho phép nó lưu trữ dữ liệu đa chiều. Các thao tác kiểu cơ sở dữ liệu hoặc SQL có thể được thực hiện dễ dàng với gấu trúc [So sánh với SQL]. Pandas cũng đi kèm với một bộ công cụ IO bao gồm các chức năng xử lý CSV, MS Excel, JSON, HDF5 và các định dạng dữ liệu khácMặc dù, chúng tôi muốn đọc dữ liệu thành cấu trúc dữ liệu giàu tính năng như gấu trúc
import pandas as pd
df = pd.read_csv['data.txt']
df
2, nhưng sẽ rất kém hiệu quả nếu tạo một import pandas as pd
df = pd.read_csv['data.txt']
df
2 trống và ghi trực tiếp dữ liệu vào đó. Một import pandas as pd
df = pd.read_csv['data.txt']
df
2 là một cấu trúc dữ liệu phức tạp và việc ghi một thứ gì đó vào một mục import pandas as pd
df = pd.read_csv['data.txt']
df
2 theo từng mục rất tốn kém về mặt tính toán. Đọc dữ liệu thành kiểu dữ liệu nguyên thủy như a b c
0 1 2 3
1 4 5 6
2 7 8 9
0 hoặc a b c
0 1 2 3
1 4 5 6
2 7 8 9
1 sẽ nhanh hơn rất nhiều. Sau khi danh sách hoặc lệnh được tạo, gấu trúc cho phép chúng tôi dễ dàng chuyển đổi nó thành import pandas as pd
df = pd.read_csv['data.txt']
df
2 như bạn sẽ thấy sau này. Hình ảnh bên dưới hiển thị quy trình tiêu chuẩn khi phân tích cú pháp bất kỳ tệp nàoNếu dữ liệu của bạn ở định dạng chuẩn hoặc đủ gần, thì có thể có một gói hiện có mà bạn có thể sử dụng để đọc dữ liệu của mình với nỗ lực tối thiểu
Ví dụ: giả sử chúng tôi có tệp CSV, dữ liệu. txt
import pandas as pd
df = pd.read_csv['data.txt']
df
1Bạn có thể xử lý việc này dễ dàng với pandas
import pandas as pd
df = pd.read_csv['data.txt']
df
2____0 a b c
0 1 2 3
1 4 5 6
2 7 8 9
Phân tích cú pháp văn bản bằng các phương thức chuỗiPython thật đáng kinh ngạc khi xử lý các chuỗi. Nó đáng để tiếp thu tất cả các hoạt động chuỗi phổ biến. Chúng ta có thể sử dụng các phương thức này để trích xuất dữ liệu từ một chuỗi như bạn có thể thấy trong ví dụ đơn giản bên dưới
import pandas as pd
df = pd.read_csv['data.txt']
df
5import pandas as pd
df = pd.read_csv['data.txt']
df
6import pandas as pd
df = pd.read_csv['data.txt']
df
7Phân tích cú pháp văn bản ở định dạng phức tạp bằng biểu thức chính quyNhư bạn đã thấy trong hai phần trước, nếu vấn đề phân tích cú pháp đơn giản, chúng ta có thể giải quyết bằng cách chỉ sử dụng trình phân tích cú pháp hiện có hoặc một số phương thức chuỗi. Tuy nhiên, cuộc sống không phải lúc nào cũng dễ dàng như vậy. Làm cách nào để phân tích cú pháp một tệp văn bản phức tạp?
Bước 1. Hiểu định dạng đầu vào
import pandas as pd
df = pd.read_csv['data.txt']
df
2____19import pandas as pd
df = pd.read_csv['data.txt']
df
0Đó là một tệp đầu vào khá phức tạp. Phù. Dữ liệu mà nó chứa khá đơn giản như bạn có thể thấy bên dưới
import pandas as pd
df = pd.read_csv['data.txt']
df
20Văn bản mẫu trông tương tự như CSV ở chỗ nó sử dụng dấu phẩy để phân tách một số thông tin. Có tiêu đề và một số siêu dữ liệu ở đầu tệp. Có năm biến. Trường, Lớp, Số học sinh, Tên và Điểm. Mã số trường, lớp và học sinh là chìa khóa. Tên và Điểm là các trường. Đối với một Trường, Lớp, Số học sinh nhất định có Tên và Điểm. Nói cách khác, Trường, Lớp và Mã số Học sinh cùng nhau tạo thành một khóa ghép
Dữ liệu được cung cấp ở định dạng phân cấp. Đầu tiên, Trường được khai báo, sau đó là Lớp. Tiếp theo là hai bảng cung cấp Tên và Điểm cho mỗi mã số Học sinh. Sau đó, lớp được tăng lên. Tiếp theo là một bộ bảng khác. Sau đó, mô hình lặp lại cho Trường khác. Lưu ý rằng số học sinh trong một Lớp hoặc số lớp trong một trường không cố định, điều này làm tăng thêm một chút phức tạp cho tệp. Đây chỉ là một tập dữ liệu nhỏ. Bạn có thể dễ dàng hình dung đây là một tập tin đồ sộ với rất nhiều trường, lớp và học sinh
Không cần phải nói rằng định dạng dữ liệu cực kỳ kém. tôi đã làm điều này trên mục đích. Nếu bạn hiểu cách xử lý vấn đề này, thì bạn sẽ dễ dàng thành thạo các định dạng đơn giản hơn rất nhiều. Không có gì lạ khi bắt gặp các tệp như thế này nếu phải xử lý nhiều hệ thống cũ. Trước đây, khi các hệ thống đó đang được thiết kế, có thể không có yêu cầu về dữ liệu đầu ra phải có thể đọc được bằng máy. Tuy nhiên, ngày nay mọi thứ cần phải được đọc bằng máy
Bước 2. Nhập các gói cần thiết
Chúng ta sẽ cần mô-đun Biểu thức chính quy và gói gấu trúc. Vì vậy, hãy tiếp tục và nhập chúng
import pandas as pd
df = pd.read_csv['data.txt']
df
21import pandas as pd
df = pd.read_csv['data.txt']
df
22Bước 3. Định nghĩa biểu thức chính quy
Ở bước cuối cùng, chúng tôi đã nhập lại, mô-đun biểu thức chính quy. Nó là gì mặc dù?
Chà, trước đó chúng ta đã thấy cách sử dụng các phương thức chuỗi để trích xuất dữ liệu từ văn bản. Tuy nhiên, khi phân tích cú pháp các tệp phức tạp, chúng ta có thể kết thúc với rất nhiều thao tác tước, tách, cắt, v.v. và mã có thể trông khá khó đọc. Đó là nơi các biểu thức chính quy xuất hiện. Về cơ bản, nó là một ngôn ngữ nhỏ được nhúng bên trong Python cho phép bạn nói mẫu chuỗi nào bạn đang tìm kiếm. Nhân tiện, nó không phải là duy nhất đối với Python [nhà trên cây]
Bạn không cần phải thành thạo các biểu thức chính quy. Tuy nhiên, một số kiến thức cơ bản về biểu thức chính quy có thể rất hữu ích trong sự nghiệp lập trình của bạn. Tôi sẽ chỉ dạy cho bạn những điều cơ bản nhất trong bài viết này, nhưng tôi khuyến khích bạn nghiên cứu thêm. Tôi cũng khuyên dùng regexper để trực quan hóa các biểu thức chính quy. regex101 là một tài nguyên tuyệt vời khác để kiểm tra biểu thức chính quy của bạn
Chúng ta sẽ cần ba biểu thức chính quy. Cái đầu tiên, như hình dưới đây, sẽ giúp chúng tôi xác định trường. Biểu thức chính quy của nó là
a b c
0 1 2 3
1 4 5 6
2 7 8 9
3. Nhưng ky hiệu nay co nghia la gi?
4. Ký tự bất kỳa b c 0 1 2 3 1 4 5 6 2 7 8 9
5. 0 hoặc nhiều hơn biểu thức trướca b c 0 1 2 3 1 4 5 6 2 7 8 9
6. Đặt một phần của biểu thức chính quy bên trong dấu ngoặc đơn cho phép bạn nhóm phần đó của biểu thức. Vì vậy, trong trường hợp này, phần được nhóm là tên của trườnga b c 0 1 2 3 1 4 5 6 2 7 8 9
7. Ký tự xuống dòng ở cuối dònga b c 0 1 2 3 1 4 5 6 2 7 8 9
Sau đó chúng ta cần một biểu thức chính quy cho lớp. Biểu thức chính quy của nó là
a b c
0 1 2 3
1 4 5 6
2 7 8 9
8. Điều này rất giống với biểu thức trước. Các ký hiệu mới là
9. Viết tắt của [0-9]a b c 0 1 2 3 1 4 5 6 2 7 8 9
50. 1 hoặc nhiều biểu thức trướcimport pandas as pd df = pd.read_csv['data.txt'] df
Cuối cùng, chúng ta cần một biểu thức chính quy để xác định xem bảng theo sau biểu thức trong tệp văn bản là một bảng tên hay điểm số. Biểu thức chính quy của nó là
import pandas as pd
df = pd.read_csv['data.txt']
df
51. Ký hiệu mới là
52. Logic hoặc câu lệnh, vì vậy trong trường hợp này, nó có nghĩa là 'Tên' hoặc 'Điểm số'. ’import pandas as pd df = pd.read_csv['data.txt'] df
Chúng ta cũng cần hiểu một số hàm biểu thức chính quy
53. Biên dịch một mẫu biểu thức chính quy thành mộtimport pandas as pd df = pd.read_csv['data.txt'] df
54import pandas as pd df = pd.read_csv['data.txt'] df
Một
import pandas as pd
df = pd.read_csv['data.txt']
df
55 có các phương thức sau
56. Nếu phần đầu của chuỗi khớp với biểu thức chính quy, hãy trả về một phiên bảnimport pandas as pd df = pd.read_csv['data.txt'] df
57 tương ứng. Nếu không, hãy trả lạiimport pandas as pd df = pd.read_csv['data.txt'] df
58import pandas as pd df = pd.read_csv['data.txt'] df
59. Quét qua chuỗi để tìm vị trí mà biểu thức chính quy này tạo ra kết quả khớp và trả về một phiên bảnimport pandas as pd df = pd.read_csv['data.txt'] df
57 tương ứng. Trả lạiimport pandas as pd df = pd.read_csv['data.txt'] df
58 nếu không có kết quả phù hợpimport pandas as pd df = pd.read_csv['data.txt'] df
Một
import pandas as pd
df = pd.read_csv['data.txt']
df
57 luôn có giá trị boolean là import pandas as pd
df = pd.read_csv['data.txt']
df
63. Do đó, chúng ta chỉ có thể sử dụng câu lệnh import pandas as pd
df = pd.read_csv['data.txt']
df
64 để xác định các kết quả phù hợp. Nó có phương pháp sau
65. Trả về một hoặc nhiều nhóm con của trận đấu. Các nhóm có thể được giới thiệu bởi chỉ số của họ.import pandas as pd df = pd.read_csv['data.txt'] df
66 trả về toàn bộ trận đấu.import pandas as pd df = pd.read_csv['data.txt'] df
67 trả về nhóm con được đặt trong ngoặc đơn đầu tiên, v.v. Các biểu thức chính quy chúng tôi sử dụng chỉ có một nhóm duy nhất. Dễ dàng. Tuy nhiên, nếu có nhiều nhóm thì sao? . Một tiện ích mở rộng cụ thể của Python cho phép chúng tôi đặt tên cho các nhóm và thay vào đó gọi chúng bằng tên của chúng. Chúng tôi có thể chỉ định một tên trong một nhóm ngoặc đơnimport pandas as pd df = pd.read_csv['data.txt'] df
68 như vậy.import pandas as pd df = pd.read_csv['data.txt'] df
69import pandas as pd df = pd.read_csv['data.txt'] df
Trước tiên chúng ta hãy định nghĩa tất cả các biểu thức chính quy. Hãy chắc chắn sử dụng chuỗi thô cho regex, tôi. e. , sử dụng chỉ số dưới
import pandas as pd
df = pd.read_csv['data.txt']
df
70 trước mỗi mẫuimport pandas as pd
df = pd.read_csv['data.txt']
df
23import pandas as pd
df = pd.read_csv['data.txt']
df
24Bước 4. Viết trình phân tích cú pháp dòng
Sau đó, chúng ta có thể định nghĩa một hàm kiểm tra các kết quả khớp regex
import pandas as pd
df = pd.read_csv['data.txt']
df
25import pandas as pd
df = pd.read_csv['data.txt']
df
26Bước 5. Viết trình phân tích tệp
Cuối cùng, đối với sự kiện chính, chúng ta có chức năng trình phân tích cú pháp tệp. Nó khá lớn, nhưng các bình luận trong mã hy vọng sẽ giúp bạn hiểu logic
import pandas as pd
df = pd.read_csv['data.txt']
df
27import pandas as pd
df = pd.read_csv['data.txt']
df
28Bước 6. Kiểm tra trình phân tích cú pháp
Chúng tôi có thể sử dụng trình phân tích cú pháp của mình trên văn bản mẫu của mình như vậy
import pandas as pd
df = pd.read_csv['data.txt']
df
29import pandas as pd
df = pd.read_csv['data.txt']
df
0import pandas as pd
df = pd.read_csv['data.txt']
df
20Điều này hoàn toàn tốt và bạn có thể thấy bằng cách so sánh đầu vào và đầu ra bằng mắt rằng trình phân tích cú pháp đang hoạt động chính xác. Tuy nhiên, cách tốt nhất là luôn viết unittests để đảm bảo rằng mã của bạn đang làm những gì bạn dự định làm. Bất cứ khi nào bạn viết một trình phân tích cú pháp, vui lòng đảm bảo rằng nó đã được kiểm tra tốt. Tôi đã gặp rắc rối với đồng nghiệp của mình vì đã sử dụng trình phân tích cú pháp mà không kiểm tra trước đó. tiếng kêu. Cũng cần lưu ý rằng đây không nhất thiết phải là bước cuối cùng. Thật vậy, rất nhiều lập trình viên giảng về Test Driven Development. Tôi đã không bao gồm một bộ thử nghiệm ở đây vì tôi muốn giữ cho hướng dẫn này ngắn gọn
Đây có phải là giải pháp tốt nhất?Tôi đã phân tích cú pháp các tệp văn bản trong một năm và hoàn thiện phương pháp của mình theo thời gian. Mặc dù vậy, tôi đã thực hiện một số nghiên cứu bổ sung để tìm hiểu xem có giải pháp nào tốt hơn không. Thật vậy, tôi biết ơn nhiều thành viên trong cộng đồng đã tư vấn cho tôi về việc tối ưu hóa mã của mình. Cộng đồng cũng cung cấp một số cách khác nhau để phân tích tệp văn bản. Một số trong số họ thông minh và thú vị. Yêu thích cá nhân của tôi là cái này. Tôi đã trình bày vấn đề mẫu và giải pháp của mình tại các diễn đàn bên dưới
- bài đăng Reddit
- bài đăng trên stackoverflow
- Bài đánh giá mã
Nếu vấn đề của bạn thậm chí còn phức tạp hơn và các biểu thức chính quy không giải quyết được, thì bước tiếp theo sẽ là xem xét phân tích cú pháp các thư viện. Đây là một vài nơi để bắt đầu với
- Phân tích cú pháp những điều khủng khiếp bằng Python. Bài giảng PyCon của Erik Rose xem xét ưu và nhược điểm của các thư viện phân tích cú pháp khác nhau
- Phân tích cú pháp trong Python. Công cụ và Thư viện. Các công cụ và thư viện cho phép bạn tạo trình phân tích cú pháp khi biểu thức chính quy không đủ
Bây giờ bạn đã hiểu việc phân tích cú pháp các tệp văn bản khó khăn và phiền phức như thế nào, nếu bạn thấy mình có quyền lựa chọn một định dạng tệp, hãy chọn nó một cách cẩn thận. Dưới đây là các phương pháp hay nhất của Stanford dành cho định dạng tệp
Tôi sẽ nói dối nếu tôi nói rằng tôi rất hài lòng với phương pháp phân tích cú pháp của mình, nhưng tôi không biết cách nào khác, để phân tích nhanh một tệp văn bản, thân thiện với người mới bắt đầu như những gì tôi đã trình bày ở trên. Nếu bạn biết về một giải pháp tốt hơn, tôi sẽ lắng nghe. Tôi hy vọng đã cung cấp cho bạn một điểm khởi đầu tốt để phân tích cú pháp một tệp bằng Python. Tôi đã dành vài tháng để thử rất nhiều phương pháp khác nhau và viết một số đoạn mã cực kỳ khó đọc trước khi tìm ra nó và bây giờ tôi không nghĩ hai lần về việc phân tích cú pháp một tệp nữa. Vì vậy, tôi hy vọng tôi đã có thể giúp bạn tiết kiệm thời gian. Vui vẻ phân tích cú pháp văn bản với python