{name} trong bản dịch bị mất, cách dừng trước khi lên mạng
Nếu {name} bị mất trong bản dịch, lỗi sẽ xảy ra trực tuyến. Sự phán xét thông thường là không đáng tin cậy. Bài viết này sử dụng thư viện chuẩn Python string.Formatter.parse để cấu trúc các phần giữ chỗ xác minh, với các ví dụ tổng hợp đúng và sai, các tập lệnh thực thi trực tiếp và ranh giới xem xét thủ công.
Trong bản dịch, các biến như {name} thường được dịch cùng nhau và trang thường không báo lỗi cho đến khi giá trị thực sự được điền vào. Nếu chỉ dựa vào mắt người hoặc biểu thức thông thường để kiểm tra dấu ngoặc nhọn trước khi lên mạng, bạn rất dễ bỏ sót chúng. Bài viết này dành cho các nhà phát triển và biên tập viên chịu trách nhiệm bản địa hóa, mẫu và kiểm tra phân phối. Nó giới thiệu cách sử dụng thư viện chuẩn Python string.Formatter.parse để thực hiện xác minh có cấu trúc trên phần giữ chỗ và giải thích những tình huống nào vẫn cần xem xét thủ công.
Sau khi đọc, bạn có thể có được ý tưởng xác minh có thể thực hiện trực tiếp: xác minh danh tính trường, tần suất xuất hiện và thông số định dạng khi bản dịch được gửi, thay vì đợi cho đến khi vấn đề được phát hiện trực tuyến. Các ví dụ sử dụng mẫu tổng hợp và mã đã được kiểm tra trong môi trường biệt lập, nhưng điều này không thể hiện sự đảm bảo về tất cả các tệp thực hoặc hiệu suất sản phẩm. Trước khi xử lý các tài liệu quan trọng, vui lòng giữ lại bản gốc và xem xét theo ranh giới và các mục chấp nhận dưới đây.
Phần giữ chỗ bị mất sau khi dịch? Một câu kết luận
Đầu tiên, sử dụng phân tích cú pháp có cấu trúc để trích xuất các trường trong chuỗi định dạng, sau đó so sánh từng trường một với các trường của bản sao nguồn; nếu tên trường, thời gian xuất hiện hoặc thông số định dạng không nhất quán, nó sẽ bị từ chối trực tiếp và việc điều chỉnh thứ tự từ sẽ được xem xét thủ công.
| hoàn cảnh của bạn | Các phương pháp được đề xuất | lý do |
|---|---|---|
| Tên biến trong bản dịch được dịch | Khôi phục tên trường giao diện trước khi giao hàng | Tên biến thuộc về hợp đồng giao diện. Sau khi thay đổi sẽ báo lỗi khi điền giá trị vào trang. |
| Bản dịch thiếu một trường có cùng tên | Từ chối bài viết và kiểm tra xem nó có thiếu bản dịch không | Số lần xuất hiện của cùng một lĩnh vực cũng là một phần của hợp đồng |
| Chỉ có vị trí trường được điều chỉnh | Chấp nhận, trật tự từ đọc có tự nhiên hay không | Những thay đổi về thứ tự trường thường không ảnh hưởng đến kết quả điền giá trị |
| Thông số định dạng như số thập phân đã thay đổi | Đánh dấu không nhất quán, xác nhận theo giao thức bản địa hóa | Thông số định dạng cũng được bảo vệ và việc có cho phép thay đổi hay không cần phải được quyết định theo thỏa thuận. |
Chọn cú pháp định dạng trước
Bài viết này chỉ đề cập đến các trình giữ chỗ kiểu Python str.format và không đề cập đến các chuỗi mẫu JavaScript, ICU MessageFormat hoặc các hệ thống giữ chỗ khác. Các hệ thống khác nhau có các quy tắc lồng, thoát và số nhiều rất khác nhau và một biểu thức chính quy không thể yêu cầu hỗ trợ tất cả chúng. Ví dụ này yêu cầu sử dụng các trường được đặt tên và từ chối các trường được đánh số tự động (chẳng hạn như {}).
Bạn có thể tìm thấy mô tả đầy đủ về cú pháp trường trong Tài liệu về chuỗi và trình định dạng Python.
Dấu ngoặc nhọn thoát không phải là biến
{{name}} đại diện cho văn bản hiển thị {name} và không được tính là một trường. Cũng có thể có các trường lồng nhau trong đặc tả định dạng, chẳng hạn như {value:{width}}. Đoạn mã bên dưới đọc đặc tả một cách đệ quy và giữ số lần xuất hiện lặp lại của cùng một trường.
from string import Formatter
from collections import Counter
def contract(text, depth=0):
if depth > 5:
raise ValueError("nested format budget")
result = Counter()
for literal, field, spec, conversion in Formatter().parse(text):
if field is None:
continue
if not field or field != field.strip():
raise ValueError("named field without surrounding whitespace required")
result[(field, conversion, spec)] += 1
if spec:
result.update(contract(spec, depth + 1))
return result
assert contract("Hi {name}, total {amount:.2f}") == contract("{name}:金额 {amount:.2f}")
assert contract("{{name}}") == Counter()
assert contract("{name} {name}") != contract("{name}")
assert contract("{value:{width}}")[("width", None, "")] == 1
assert contract("{amount:.2f}") != contract("{amount:.0f}")
for bad in ["Hi {name", "{ name}", "{}"]:
try:
contract(bad)
except ValueError:
pass
else:
raise AssertionError("invalid template accepted")
Hợp đồng này cố tình nghiêm ngặt
Thông số định dạng cũng được coi là nội dung được bảo vệ ở đây nên việc thay đổi số vị trí thập phân sẽ bị gắn cờ. Một số tác vụ bản địa hóa yêu cầu thay đổi cách trình bày số, trong trường hợp đó bạn nên tạo quy tắc riêng cho điều đó thay vì hủy tất cả các kiểm tra giữ chỗ. Giới hạn độ sâu lồng nhau trong ví dụ là ngân sách trình diễn và không phải là yêu cầu của đặc tả ngôn ngữ.
Bảng sau liệt kê một số loại thay đổi phổ biến và phương pháp xử lý tương ứng của chúng:
| thay đổi | Kết quả của ví dụ này | xem xét hành động |
|---|---|---|
| Thay đổi trường | chấp nhận | Thứ tự từ khi đọc có tự nhiên không? |
| Trường tương tự bị thiếu một lần | từ chối hợp đồng | Kiểm tra các bản dịch bị thiếu |
| Tên biến được dịch | từ chối hợp đồng | Tên trường giao diện khôi phục |
| Thay đổi thông số thập phân | Thẻ không nhất quán | Xác nhận theo thỏa thuận nội địa hóa |
📊 So sánh cốt lõi
| Thay đổi loại | Liệu nó có vượt qua được quá trình xác minh hay không | Hành động tiếp theo |
|---|---|---|
| Thay đổi trường | vượt qua | Thứ tự từ khi đọc có tự nhiên không? |
| Trường tương tự bị thiếu một lần | thất bại | Kiểm tra các bản dịch bị thiếu |
| Tên biến được dịch | thất bại | Tên trường giao diện khôi phục |
| Thay đổi thông số thập phân | Đánh dấu là không nhất quán | Xác nhận theo thỏa thuận nội địa hóa |
🎯 Phương pháp nào phù hợp với bạn?
Nếu bạn chịu trách nhiệm cung cấp bản dịch
Chạy kiểm tra cấu trúc trước khi gửi và trả lại các mục bị từ chối cho người dịch có tên trường bị thiếu hoặc bị thay đổi.
Nếu bạn chịu trách nhiệm về mẫu và giao diện
Nêu rõ tên trường nào thuộc hợp đồng giao diện và liệt kê chúng trong hướng dẫn phân phối để người dịch và người đánh giá dễ dàng so sánh.
Nếu bạn cần thay đổi cách trình bày số
Phát triển giao thức bản địa hóa riêng cho thông số kỹ thuật định dạng và thêm nó vào quy tắc xác minh thay vì tắt kiểm tra tổng thể.
❓ Câu hỏi thường gặp (FAQ)
1. Phương pháp này có thể xử lý các mẫu JavaScript hoặc ICU MessageFormat không?
không thể. Bài viết này chỉ tập trung vào các trường được đặt tên theo kiểu Python str.format. Các quy tắc lồng, thoát và số nhiều của các hệ thống khác cần được xử lý riêng.
2. {{name}} có được kiểm tra dưới dạng biến không?
Sẽ không. Nó đại diện cho văn bản hiển thị {name}, văn bản này không được tính là một trường khi được phân tích cú pháp.
3. Nếu tôi chỉ điều chỉnh vị trí của trường trong câu thì có bị từ chối không?
Sẽ không. Những thay đổi về vị trí trường được chấp nhận trong trường hợp này và sau đó được đọc thủ công để xem thứ tự từ có tự nhiên hay không.
4. Tôi có thể gọi trực tiếp cho format để xác minh bản dịch không?
Mã trong bài viết này chỉ thực hiện phân tích cú pháp và không thực sự gọi format để điền vào đối tượng. Nó không phải là một hộp cát bảo mật mẫu. Việc hiển thị tiếp theo cũng yêu cầu các hạn chế đối với các trường có sẵn, bối cảnh truy cập và đầu ra đối tượng, đặc biệt là các quy tắc thoát trong các trang HTML.
📝 Tóm tắt
Việc sử dụng phân tích cú pháp có cấu trúc để kiểm tra phần giữ chỗ trong quá trình phân phối bản dịch có thể ngăn chặn các vấn đề về tên trường, thời gian và thông số định dạng trước khi đưa lên mạng. Ngôn ngữ có trôi chảy hay không vẫn cần được người đánh giá đánh giá riêng.
Thử ngay: Tải tài liệu lên để bắt đầu dịch, giữ nguyên bố cục ban đầu


