Là đặt đánh dấu văn bản bên trong chuỗi phong cách xấu? Có một sự thay thế?


10

Tôi làm việc với các chuỗi lớn cần nhiều thao tác.

Ví dụ: tôi có thể tạo một chuỗi như thế này:


Thuyền phần 1

Phần A
Lập trình

Phần 2
Phân vùng thuyền để lập trình.

Mục AA
Mục nhập SQL.

Chuỗi sẽ quá lớn để kiểm tra thủ công từng phần của nó. Bây giờ tôi cần splitđiều này stringthành một stringlistphần và các phần. Tôi có thể nghĩ về hai lựa chọn:

Một biểu hiện thường xuyên:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

Có vẻ như nó sẽ hoạt động, nhưng đôi khi các trường hợp ngoại lệ lướt qua (IE: Section SQL Entriessẽ bị chia tách một cách sai lầm)

Mặt khác, những gì tôi có thể làm là đặt một điểm đánh dấu khi tôi tạo chuỗi ban đầu:

ArtBắt 1
thuyền

Phần
lập trình

Bắt 2
thuyền phân vùng để lập trình.

Số
mục nhập Mục SQL.

Điều đó có nghĩa là việc tách chuỗi sẽ trở nên dễ dàng:

QStringList sl = s.split("🚤💻"));

Một cái gì đó cho tôi biết rằng cả hai đều không phải là phong cách tốt hoặc thực hành lập trình, nhưng tôi đã cho đến thời điểm này không thảo luận về nó và cũng không tìm thấy một sự thay thế.

  • Nếu bạn là người quản lý dự án của tôi, bạn có chấp nhận một trong hai phương pháp này không?
  • Nếu không, bạn sẽ đề nghị tôi làm gì như một cách thực hành tốt nhất?

6
Nếu chương trình của bạn biết nơi đặt các điểm đánh dấu này, tại sao không tạo các phần dưới dạng các chuỗi riêng biệt để bắt đầu?
Jacob Raihle

Tôi không nghĩ người dùng một điểm đánh dấu không dịch tốt vào mã hóa hiện tại của bạn là một ý tưởng hay.
Tulains Córdova

2
các biểu tượng thực tế được sử dụng phần lớn không liên quan, điều sẽ tạo ra sự khác biệt là ngữ pháp của điều bạn đang cố gắng phân tích
jk.

4
@Akiva bạn có chắc chắn về hiệu suất hit? Bạn đang làm việc với cùng một lượng dữ liệu trong mọi trường hợp, tôi nghi ngờ sẽ có một sự khác biệt đáng kể. Kết hợp hàng ngàn hàm thành một hàm, gọi nó trong một vòng lặp và thực hiện một số phép đo.
Jacob Raihle

2
@Akiva Lấy và thay thế các phần tử trong danh sách tệ nhất có thể so sánh với việc tách một chuỗi lớn.
Jacob Raihle

Câu trả lời:


17

Thực tế không phải là mã hóa tài liệu được nhúng dưới dạng văn bản trong một chuỗi. Hãy nghĩ về markdown, HTML, XML, JSON, YAML, LaTeX, v.v.

Thực hành xấu là gì đang phát minh lại bánh xe. Thay vì viết bộ xử lý văn bản của riêng bạn, hãy nghĩ về việc sử dụng một tiêu chuẩn hiện có. Có rất nhiều phần mềm miễn phí thực hiện nhiều phân tích cú pháp cho bạn và nhiều phần mềm có giấy phép không hạn chế cho phép bạn sử dụng phần mềm nói trên trong phần mềm độc quyền của riêng bạn.


Trong trường hợp của tôi, tôi đang phát minh ra một bánh xe, nếu điều tôi đang cố gắng làm là xây dựng một trình thông dịch duy nhất cho một ngôn ngữ đánh dấu. Ví dụ, một trong những dự án của tôi đã diễn giải latex là SSML mà tai người có thể đọc được: meta.wik hè.org / wiki / Grant : IdeaLab / . << Có một khoảng thời gian ở cuối URL đó, nếu không nó sẽ không hoạt động
Akiva

2
@Akiva Tôi phải làm việc với một định dạng văn bản tùy chỉnh được phát triển bởi nơi làm việc của tôi, nghĩa là tái tạo bánh xe. Tôi phải duy trì 4 trình phân tích cú pháp bằng 3 ngôn ngữ (Javascript, Java và Objective-C) cho nó và đó là một cơn ác mộng đáng sợ . Làm điều đúng ngay bây giờbãi bỏ định dạng văn bản tùy chỉnh vô nghĩa này . Tôi không thể nhấn mạnh đủ cách lớn của một cơn ác mộng bảo trì này sẽ trở thành một vài năm xuống đường. Sử dụng các định dạng có cấu trúc, XML, JSON, v.v.
Chris Cirefice

@ChrisCirefice Bạn có thể cho tôi một ví dụ về cách nó là một cơn ác mộng?
Akiva

1
@Akiva Tôi nghĩ rằng việc bạn phải duy trì ngay cả một trình phân tích cú pháp (trong trường hợp của tôi là một số ngôn ngữ khác nhau) là khủng khiếp. Các định dạng tiêu chuẩn tồn tại vì một lý do - chúng có thể đại diện cho dữ liệu bạn cần chúng - và với rất ít nỗ lực từ phía bạn, bởi vì các trình phân tích cú pháp đã được xây dựng, tinh chỉnh và được duy trì. Định dạng văn bản tùy chỉnh cũng là kiến ​​thức cực kỳ chuyên biệt, có nghĩa là thường chỉ có một hoặc hai nhà phát triển sẽ đủ quen thuộc với định dạng để duy trì thành công. Điều đó sẽ nói lên khối lượng. Hầu hết mọi người đều quen thuộc với CML, JSON - ít người biết các định dạng tùy chỉnh.
Chris Cirefice

1
@Akiva Thật vậy! Định dạng đánh dấu (những gì SE và nhiều trang web khác sử dụng để định dạng văn bản) có phần chuẩn , giống như SQL. Nhưng có nhiều 'hương vị' khác nhau với các tiện ích mở rộng tùy chỉnh (ví dụ như SE). Có một thư viện chuẩn phân tích 'lõi', sau đó bạn mở rộng thư viện nếu bạn muốn các tính năng bổ sung. Nhưng, việc xây dựng và duy trì trình định dạng của riêng bạn sẽ là lố bịch - một số đã tồn tại (markdown, mã BB, ​​v.v.), vậy tại sao phải phát minh lại bánh xe và duy trì tất cả mã đó? Cũng có thể chỉ sử dụng một thư viện hiện có :)
Chris Cirefice

8

Sử dụng một số dấu tách phổ biến sẽ hoạt động tốt khi tách các chuỗi tùy ý lớn hơn, nhưng tôi khuyên bạn không nên sử dụng ký hiệu tùy ý. Ai đó đọc chuỗi đó dưới dạng bản rõ có thể bị nhầm lẫn, chưa kể các rắc rối với UTF và liệu biểu tượng có xuất hiện bên trong các phần hay không.

Phần quan trọng nhất của điều này là mỗi phần vẫn còn nguyên, trong khi mỗi "tiêu đề của phần" cần được xác định một cách thích hợp.

Tại sao không sử dụng một dấu phân tách phổ biến nhưng giữ cho nó có thể đọc được? Cái gì đó như:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Vấn đề là quyết định dải phân cách là gì, vì nó cần phải là thứ được đảm bảo để không hiển thị bất kỳ phần nào. Bạn có thể xác định thêm nó là một dấu phân cách bằng cách yêu cầu nó nằm ở đầu một dòngvăn bản duy nhất trên dòng đó .

Nếu không có thêm kiến ​​thức về văn bản nào được mong đợi trong mỗi phần, thật khó để đưa ra khuyến nghị về phân cách chung nào sẽ tốt nhất trong trường hợp này.


Tôi thích sự nhấn mạnh câu trả lời của bạn về khả năng đọc. Các chuỗi được tạo thông qua văn bản quét dữ liệu do người dùng tạo, ví dụ, ngôn ngữ Đánh dấu được sử dụng trong SE để viết câu hỏi và câu trả lời. Vì vậy, bạn có thể dễ dàng tưởng tượng loại vấn đề thao tác chuỗi nào có thể xảy ra.
Akiva

5

Câu trả lời được chấp nhận dường như đã bỏ lỡ những gì bạn đã viết trong một bình luận:

Lý do là rất nhiều thao tác tôi thực hiện đòi hỏi phải có chuỗi đầy đủ

và đưa ra điều này như một ví dụ:

s.replace ("thuyền", "lập trình");

Nếu đó là những gì bạn muốn, thì IMHO là một ý tưởng thực sự tồi khi sử dụng một số "đánh dấu" hoặc dấu tách văn bản cho toàn bộ chuỗi của bạn, điều này luôn có một rủi ro nhất định để can thiệp vào thao tác và sẽ không dẫn đến mã mạnh. Đặc biệt là khi bạn cố gắng bắt đầu sử dụng các biểu thức chính quy trên một chuỗi kết hợp như vậy, có thể bạn sẽ gặp phải các vấn đề tương tự mà mọi người quan sát thấy khi cố gắng phân tích HTLM hoặc XML bằng các biểu thức thông thường .

Đặc biệt bởi vì bạn đã viết có thể có "hàng ngàn chức năng [thao tác như vậy]", nguy cơ đó có thể trở thành một vấn đề thực sự. Ngay cả khi bạn sử dụng một số đánh dấu như XML để lưu trữ danh sách chuỗi bên trong, bạn cần đảm bảo rằng thao tác sẽ chỉ xử lý nội dung chứ không phải đánh dấu, do đó có nghĩa là chia chuỗi thành các phần trước khi bạn thực hiện bất kỳ xử lý nào và tham gia sau đó một lần nữa - do đó sẽ có nguy cơ cao mang lại cho bạn một hiệu suất tồi.

Cách thay thế thiết kế tốt hơn ở đây là cung cấp một kiểu dữ liệu trừu tượng (sử dụng một lớp nếu bạn muốn), gọi nó MyStringListvà cung cấp một tập hợp nhỏ các thao tác cơ bản cho phép bạn thực hiện "hàng ngàn hàm" của mình theo các thao tác đó. Ví dụ, có thể có chung findreplacehoạt động, hoặc một maphoạt động chức năng chung . Bạn cũng có thể thêm một cái gì đó giống như một JoinToStringhoạt động nếu bạn thực sự cần toàn bộ danh sách trong một chuỗi cho một số con ngựa nhất định.

Sử dụng các hoạt động này, bạn sợ rằng mã trở nên phức tạp hơn vì "mọi thứ sẽ phải được thực hiện trong một vòng lặp for" trở nên vô nghĩa, bởi vì các forvòng lặp duy nhất bạn nhận được được gói gọn trong các hoạt động của kiểu dữ liệu. Và tôi sẽ không quan tâm đến hiệu suất cho đến khi bạn có tác động hiệu suất thực sự, có thể đo lường được (điều mà tôi nghi ngờ bạn nhận được nếu bạn thực hiện đúng các thao tác cơ bản).


Upvote bởi vì tôi đã thực sự tạo ra một cái gì đó như thế. Nó cho phép tôi đặt dấu ngoặc tùy chỉnh, <>, nó sẽ lấy mọi phiên bản của chuỗi đó, nơi tôi có thể dễ dàng loại bỏ các trường hợp tôi không muốn và thao tác sạch theo cách tôi muốn. Điều này là tốt bởi vì các biểu thức chính quy tự chúng không xử lý các chuỗi con như thế này: <boat <programming>>nơi có nhiều lớp dấu ngoặc.
Akiva

1

Định dạng được mô tả rất giống với các tệp INI:

https://en.wikipedia.org/wiki/INI_file

Trong trường hợp đó, phần được bao quanh bởi dấu ngoặc vuông [] vì vậy những gì bạn mô tả có ý nghĩa bằng cách đánh dấu phần đó theo cách nào đó để thêm ý nghĩa bổ sung cho văn bản đó.


0

Ví dụ: tôi có thể tạo một chuỗi như thế này:

Câu hỏi: Từ những gì bạn "tạo ra" chuỗi này?

Điều đó sẽ dễ dàng hơn để thao tác?


Chuỗi được tạo từ Datascraping nội dung người dùng từ một trang web.
Akiva

1
Đây không phải là một cách đáng tin cậy để lấy dữ liệu từ một trang web, đơn giản là vì chúng thay đổi và mọi thứ bị di chuyển xung quanh hoặc biến mất hoàn toàn. Bạn sẽ tốt hơn nhiều khi lấy dữ liệu từ một số loại API được xuất bản (và do đó đáng tin cậy). Hơn nữa, việc sử dụng nhiều trang web thương mại đặc biệt cấm loại điều này.
Phill W.

Đôi khi tôi không thể chọn dữ liệu nào có giá trị đối với mình và vì vậy luôn cần phải kiểm tra tính toàn vẹn cho những gì bạn đang xem hoặc chỉ đơn giản là thỏa hiệp và hy vọng điều tốt nhất. Ví dụ: Tôi đã viết một LaTeXđể SSMLthông dịch viên, và một trong những vấn đề là bạn có thể tạo ra hình ảnh giống hệt với mã rất khác nhau, và vì vậy nó là gần như không thể để phù hợp nếu người dùng chọn cách nghèo hoặc bí truyền tạo ra công thức của mình. Tất cả điều đó có nghĩa là vào cuối ngày là những người không sử dụng thực hành tốt sẽ không có một sự giải thích đúng đắn về kịch bản của họ.
Akiva
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.