Skip to content

fix: simpleText 的空白正则会删掉正文里的 ]] - #7712

Open
kevin9327 wants to merge 1 commit into
labring:mainfrom
kevin9327:fix/simple-text-whitespace-regex
Open

kevin9327 wants to merge 1 commit into
labring:mainfrom
kevin9327:fix/simple-text-whitespace-regex

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

现象

往知识库里导入一段带 ]] 的文本,]] 会凭空消失:

原文 入库后
参考 [[ 知识库 ]] 一节 参考 [[ 知识库 一节
{"matrix": [[]]} {"matrix": [ }
value = arr[ ]] value = arr[

同时 simpleText 注释里写的 “remove chinese space” 一直没生效:中文 中文 原样保留,多余空白也没有被压缩。

原因

packages/global/common/string/tools.ts 的两条规则用了字符组交集写法:

text = text.replace(/([-])[\s&&[^\n]]+([-])/g, '$1$2');
text = text.replace(/[\s&&[^\n]]{2,}/g, ' ');

&& 交集只在 v 标志下成立。没有 v 时字符组在第一个 ] 处就闭合了(组内是空白、&[^),后面那个 ] 变成字面量并被量词修饰。所以第二条规则实际匹配的是「一个空白/[/&/^ + 两个及以上 ]」,命中后整段替换成一个空格 —— 空白没压缩,反而把正文的 ]] 删掉了;第一条同理,删的是中文之间的 ]

simpleText 在这些路径上都会跑到:textSplitter 的每个分块、simpleMarkdownText / readFileRawText(含 Doc2X 等解析结果)、以及 /api/core/dataset/data/insertData

修改

改用 [^\S\r\n](除换行外的空白,顺带覆盖全角空格 U+3000)。

压缩行内空白那条加了 (?<=\S):只压缩行内多余空白,保留行首缩进,避免把知识库里代码块的缩进压掉。(replaceSensitiveText 已经在用后行断言,运行环境一致。)

因为这一步以前从未真正生效,有 3 处旧断言记录的是当时的实际行为,需要跟着更新:

  • simpleText('a b')'a b''a b'
  • simpleText(' 你 好 \r\n\r\n\r\nfoo\x00bar ')'你 好 \n\nfoo bar''你好 \n\nfoo bar'(注释承诺的中文空格去除现在生效了)
  • parseMarkdownBase64Images('before ![alt](data:…) after')'before after''before after'(图片被删后留下的双空格现在会被压成一个)

如果你们更希望完全保持现状、不启用空白压缩,我可以把第二条规则直接去掉,只保留「不再删 ]]」这部分,改动会更小 —— 按你们的偏好来即可。

验证

cd packages/global
vitest run --config vitest.config.ts --coverage.enabled=false --maxWorkers=1 --no-fileParallelism \
  test/common/string/tools.test.ts test/common/string/markdown.test.ts
  • 修改前(只加测试、不改实现):Test Files 1 failed | 1 passed (2)Tests 3 failed | 56 passed (59)
    • expected '参考 [[ 知识库 一节' to be '参考 [[ 知识库 ]] 一节'
    • expected '中文 中文' to be '中文中文'
    • expected '你 好 \n\nfoo bar' to be '你好 \n\nfoo bar'
  • 修改后,跑完整目录 test/common/stringTest Files 7 passed (7)Tests 130 passed (130)

新增的回归用例同时钉住了「不删 ]]」和「保留行首缩进」:

expect(simpleText('参考 [[ 知识库 ]] 一节')).toBe('参考 [[ 知识库 ]] 一节');
expect(simpleText('{"matrix": [[]]}')).toBe('{"matrix": [[]]}');
expect(simpleText('def f():\n    return 1')).toBe('def f():\n    return 1');

prettier --checkgit diff --check 均通过。

`[\s&&[^\n]]` 是 v 标志下的字符组交集写法,普通正则里末尾的 `]` 会被当成
字面量,于是这两条规则实际匹配的是「一个空白/[/&/^ + 一个或多个 ]」:

- 中文之间的空格没有被去掉;
- 行内多余空白没有被压缩;
- 反而会把正文里的 `]]` 删掉,例如 `参考 [[ 知识库 ]] 一节` 入库后变成
  `参考 [[ 知识库  一节`,`{"matrix": [[]]}` 变成 `{"matrix": [ }`。

改用 `[^\S\r\n]`(除换行外的空白)。压缩行内空白时加 `(?<=\S)`,保留行首
缩进,避免破坏知识库里的代码块。
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cla-assistant

cla-assistant Bot commented Sep 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

text = text.replace(/\n{3,}/g, '\n\n');
text = text.replace(/[\s&&[^\n]]{2,}/g, ' ');
// \u53ea\u538b\u7f29\u884c\u5185\u591a\u4f59\u7a7a\u767d\uff0c\u884c\u9996\u7f29\u8fdb\u4fdd\u7559\uff0c\u907f\u514d\u7834\u574f\u4ee3\u7801\u5757\u3002
text = text.replace(/(?<=\S)[^\S\r\n]{2,}/g, ' ');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 当前正则没有要求空白后是非空白字符,因此会把行尾空格也压缩掉。例如 line \\nnext 会变成 line \\nnextsimpleMarkdownText 会先调用 simpleText,这可能破坏 Markdown 用两个行尾空格表示硬换行的语义。若目标仅是压缩词间空白,建议改为 /(?<=\\S)[^\\S\\r\\n]{2,}(?=\\S)/g 并补充行尾空格测试;如果需要全局压缩,请明确记录代码/JSON 字符串也会被改写的预期。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants