【问题标题】:Google Docs API: "The insertion index cannot be within a grapheme cluster"Google Docs API:“插入索引不能在字素簇内”
【发布时间】:2019-11-12 18:48:22
【问题描述】:

在使用 Google Docs API 将某些 Unicode 字符写入 Google Doc 时,我被 400 状态困扰:

HttpError:https://docs.googleapis.com/v1/documents/xxxxxxxxx:batchUpdate?alt=json 返回“无效请求[0].insertText:插入索引不能位于字素簇内。”>

我已设法将其归结为最小的示例。下面的例程尝试插入(按顺序):

  • 泰文字符串'ถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ'
  • 在上述字符串上方/之前的换行符

代码:

from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

SCOPES = [
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/drive.appdata",
    "https://www.googleapis.com/auth/drive.metadata",
]

credentials = Credentials.from_service_account_file("data/gdocscredentials.json", scopes=SCOPES)
svc = build("docs", "v1", credentials=credentials).documents()

requests = [ 
    {
        "insertText": {
            "location": {
                #  The zero-based index, in UTF-16 code units
                "index": 1
            }, 
            "text": "ถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ"
        }
    },
    {"insertText": {"location": {"index": 1}, "text": "\n"}}

]
svc.batchUpdate(
    documentId="xxxxxxxxx",
    body={"requests": requests}
).execute()

因此,错误暗示泰语字符串包含(或存在)字素簇。 docs refer to this

API 可能会隐式调整位置以防止插入 Unicode 字素簇。发生这种情况时,文本会立即插入到字素簇之后。

如何正确纠正此错误

Google mentions that索引以 UTF-16 代码单元衡量。但这似乎并不重要,因为此代码 sn-p 使用的是同一文档页面本身推荐的“向后工作”方法。

【问题讨论】:

    标签: python python-3.x google-docs google-docs-api


    【解决方案1】:

    这个答案怎么样?

    问题及解决方案:

    ถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ 的字符为 2 个字节。我认为你的问题的原因是由于这个。当试图将文本放在 2 字节字符的中心时,就会出现这样的错误。

    从您的请求正文中,我认为您想将ถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ 放入索引1,然后将换行符\n 放入索引1。在这种情况下,\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ 是同样的情况。

    示例情况1:

    将文本放入新的 Google 文档时,可以使用以下请求正文。

    requests = [
        {"insertText": {"location": {"index": 1}, "text": "\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ"}}
    ]
    
    • 当您当前的请求正文用于新的 Google 文档时,{"insertText": {"location": {"index": 1}, "text": "\n"}} 会出现错误。因为\n"index": 1 不能放在2 字节字符中。

    示例情况2:

    当文本被放入包含泰文字符的谷歌文档时,可以使用以下请求正文。

    requests = [
        {"insertText": {"location": {"index": 2}, "text": "\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ"}}
    ]
    
    • "index": 2 用于现有的 2 字节字符。
    • 在这种情况下,如果ถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ 的文本已经存在于第一段,则\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ 的附加文本会拆分现有文本,如ถ\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ。这样,不能将 2 字节字符放入现有 2 字节字符的 Document 的第一个索引中。不幸的是,在现阶段,我认为这是由于谷歌方面的问题。
    • 如果sample的1字节字符的文本已经存在到第一段,则\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับ的附加文本就像\nถ้ามีลูกแล้วไม่ส่งเรียนพิเศษอะไรเลย จะเป็นอะไรไหมครับsample一样放置。

    参考:

    如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

    【讨论】:

    • 谢谢,这似乎是部分解决方案,但我也很难理解为什么会发生错误。在我的代码中,换行符放在任何 2 字节字符的 before 之前,而不是它们的“中心”。 (你甚至可以尝试{"insertText": {"location": {"index": 0}, "text": "\n"}},使用0 而不是`,仍然会失败。)
    • @Brad Solomon 感谢您的回复。我带来的不便表示歉意。为了重现该问题,需要确认示例 Google 文档。那你能提供吗?当然,请删除您的个人信息。如果您能合作解决您的问题,我很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多