số đăng ký sed / awk trong công thức hóa học bằng cách sử dụng thẻ đánh dấu


7

Tôi có hàng trăm tệp văn bản bao gồm các công thức hóa học cùng với tường thuật bao gồm các giá trị số. Các công thức luôn đi trước các khoảng trắng nhưng có thể được theo sau bởi các khoảng trắng, dấu phẩy, dấu chấm, v.v.

Vấn đề là: các công thức không được định dạng để hiển thị số dưới dạng các mục con, ví dụ:

H2SO4, C5H11OH.

Tôi muốn định dạng các mục con dưới dạng thẻ HTML, ví dụ:

H<sub>2</sub>SO<sub>4</sub>, C<sub>5</sub>H<sub>11</sub>OH

Vì vậy, các mục đăng ký hiển thị trong HTML, ví dụ:

H 2 SO 4 , C 5 H 11 OH

Tôi đã chơi với việc hoàn thành việc này với Java, php, v.v., nhưng việc triển khai nhất thiết phải lộn xộn và vụng về. Tôi nghi ngờ rằng có một cách tiếp cận sed / awk thanh lịch.

Rõ ràng, một phần của giải pháp là tạo ra một biểu thức chính quy khớp với một chữ cái theo sau một hoặc nhiều chữ số làm cơ chế phát hiện công thức (có thể có những lỗi sai mà tôi sẽ sửa thủ công sau này). Sau đó, được đưa ra một công thức đã được xác định, một sự thay thế sed cần đặt trước mỗi chữ số hoặc chuỗi các chữ số với subthẻ và tuân theo nó với việc đóng thẻ phụ.

Phải có một lớp lót làm được điều này, nhưng tôi ở trên đầu.

Có ý kiến ​​gì không?


Vì vậy, có một lý do bạn đã thêm một hình ảnh chứ không phải là một khối mã nội tuyến? Xem thêm trợ giúp định dạng: trung tâm trợ giúp
mèo

Câu trả lời:


4

Ví dụ:

sed -r 's:([A-Za-z])([0-9]+):\1<sub>\2</sub>:g'  

nên làm công việc.

(Ghép một chữ cái theo sau bởi một nhóm chữ số và ghi nhớ nó là \ 1 và \ 2. Thay thế tất cả các chữ cái đó bằng cùng một chữ cái (\ 1) cộng với nhóm chữ số (\ 2) được đính kèm trong subthẻ.)


3

Vì bạn đề cập có thể có các lỗi tích cực để sửa thủ công sau này, bạn có thể muốn xem xét một hình thức mạnh mẽ hơn một chút kết hợp các hạn chế sau:

  1. Tất cả các ký hiệu hóa học bắt đầu bằng một chữ cái viết hoa.
  2. Tất cả các ký hiệu hóa học là một chữ cái viết hoa đơn hoặc một chữ cái viết hoa đơn theo sau là một chữ cái viết thường, ngoại trừ chỉ các ký hiệu tạm thời mà tôi sẽ bỏ qua.

Cho những cái này bạn có thể thử, ví dụ:

sed 's|\([[:upper:]][[:lower:]]\{0,1\}\)\([0-9]\{1,\}\)|\1<sub>\2</sub>|g'

Với -rtùy chọn không phải POSIX, điều này trở nên dễ đọc hơn nhưng ít di động hơn:

sed -r 's|([[:upper:]][[:lower:]]?)([0-9]+)|\1<sub>\2</sub>|g'

Điều này có thể được cải thiện hơn nữa bằng cách đảm bảo rằng toàn bộ "từ" đang được xử lý không chứa các chữ cái viết thường liên tiếp, và tất nhiên có thể được cải thiện hơn nữa bằng cách kiểm tra cụ thể cho từng ký hiệu hóa học có thể, nhưng nó được fancier và fancier ít trả hơn. Ở trên nên giảm đáng kể dương tính giả.


2
Theo unix.stackexchange.com/questions/267148/, bạn có thể sử dụng -Ethay vì -rvà vẫn là "POSIX-y".
Dani_l

Nó không kém di động - nó cũng dễ mang theo như cái đầu tiên (nghĩa là không di động; đối với BRE di động, hãy xem câu trả lời của OP).
don_crissti

@don_crissti, phần nào trong lệnh đầu tiên của tôi không phải là POSIX?
tự đại diện

1
\?\+... gnu sedvà các ứng dụng / triển khai khác là "thông minh" để họ hiểu các vòng loại đó ngay cả khi - theo tiêu chuẩn - chúng không phải là BRE.
don_crissti

@don_crissti, cảm ơn; Tôi chưa bao giờ nhận ra điều đó. Tôi thấy rằng nó không hoạt động trong BSD sednhư được viết ban đầu. Bây giờ tôi đã sửa nó để sử dụng bộ định lượng POSIX được chỉ định .
tự đại diện

2

Tham chiếu nhóm và trở lại là mẹo. Cảm ơn đã đẩy đúng hướng. Cuối cùng, tôi đã sử dụng như sau:

sed 's/\([A-Z][a-z]*\)\([0-9][0-9]*\)/\1<sub>\2<\/sub>/g' file

Điều này chấp nhận các trường hợp trong đó một tiêu đề, ví dụ h2, xảy ra trong tài liệu.

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.