diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7435634..520ac20 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+---
+
+## [1.7.1] - 2026-05-28
+
+### ✨ New Features
+
+- **Display name regex replacement** (closes [#37](https://github.com/Moyf/easy-copy/issues/37)): added a "Display name: Regex replacement" option under Special copy format options. When enabled, a find-and-replace (with full regex support including capture groups like `$1`) is applied to the display text of copied heading/note links. Useful for stripping leading numbers (e.g. `^\d+\.\s*`) or other prefixes from headings.
+
+
+中文说明(点击展开)
+
+### ✨ 新功能
+
+- **显示名称正则替换**(修复 [#37](https://github.com/Moyf/easy-copy/issues/37)):在「特殊复制格式选项」中新增「显示名称:正则替换」选项。启用后,可对复制的标题/笔记链接的显示文本进行正则查找替换,支持 `$1` 等捕获组引用。适合去除标题前的序号(如 `^\d+\.\s*`)等场景。
+
+
+
---
## [1.7.0] - 2026-05-26
diff --git a/README.md b/README.md
index 439f4e4..307fa5e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Easy Copy - Make Copying Smart and Simple!
-English | [中文文档](./README-zh.md)
+English | [中文文档](https://github.com/Moyf/easy-copy/blob/master/README-zh.md)
   
diff --git a/manifest.json b/manifest.json
index 9d76a54..844395a 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"id": "easy-copy",
"name": "Easy Copy",
- "version": "1.7.0",
+ "version": "1.7.1",
"minAppVersion": "1.8.7",
"description": "Easily copy the text within inline code, bold text (and many other formats), or quickly generate an elegant link to a heading.",
"author": "Moy",
diff --git a/package.json b/package.json
index 63b2047..f0e71c5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "easy-copy",
- "version": "1.7.0",
+ "version": "1.7.1",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"main": "main.js",
"scripts": {
diff --git a/src/i18n.ts b/src/i18n.ts
index ec1b63c..d6208a3 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -46,7 +46,10 @@ export type TranslationKey =
| 'block-display-word-limit' | 'block-display-word-limit-desc'
| 'block-display-char-limit' | 'block-display-char-limit-desc'
| 'generate-current-block-link-auto' | 'generate-current-block-link-manual'
- | 'error-block-id-empty' | 'error-block-id-invalid';
+ | 'error-block-id-empty' | 'error-block-id-invalid'
+ | 'enable-display-name-regex' | 'enable-display-name-regex-desc'
+ | 'display-name-regex-from' | 'display-name-regex-from-desc'
+ | 'display-name-regex-to' | 'display-name-regex-to-desc';
// 本地化翻译字典
export const translations: Record> = {
@@ -163,6 +166,12 @@ export const translations: Record> = {
'generate-current-block-link-auto': 'Copy current block link (auto-generate ID)',
'generate-current-block-link-manual': 'Copy current block link (manual ID input)',
'file-link-copied': 'File link copied!',
+ 'enable-display-name-regex': 'Display name: Regex replacement',
+ 'enable-display-name-regex-desc': 'When enabled, apply a regex find-and-replace to the display text of copied heading/note links',
+ 'display-name-regex-from': 'Find (regex)',
+ 'display-name-regex-from-desc': 'Regular expression pattern to match in the display text (e.g. ^\\d+\\.\\s* to remove leading numbers)',
+ 'display-name-regex-to': 'Replace with',
+ 'display-name-regex-to-desc': 'Replacement string, supports capture groups like $1, $2 (e.g. $1 to keep only the first captured group)',
},
[Language.ZH]: {
// 复制 Block ID
@@ -275,6 +284,12 @@ export const translations: Record> = {
'block-display-word-limit-desc': '使用空格分隔的语言(如英语 "this is a sentence")在块显示文本中显示的最大单词数',
'block-display-char-limit': '块显示文本:CJK 类语言的字符数限制',
'block-display-char-limit-desc': '非英语类语言(如中文 "这是一句话")在块显示文本中显示的最大字符数——当第一行包含非ASCII字符时,会采用此设置。',
+ 'enable-display-name-regex': '显示名称:正则替换',
+ 'enable-display-name-regex-desc': '启用后,对复制的标题/笔记链接的显示文本进行正则查找替换',
+ 'display-name-regex-from': '查找(正则)',
+ 'display-name-regex-from-desc': '用于匹配显示文本的正则表达式(如 ^\\d+\\.\\s* 可去除开头的序号)',
+ 'display-name-regex-to': '替换为',
+ 'display-name-regex-to-desc': '替换字符串,支持捕获组引用如 $1、$2(如 $1 只保留第一个捕获组的内容)',
},
[Language.ZH_TW]: {
// 复制 Block ID
@@ -388,6 +403,12 @@ export const translations: Record> = {
'use-frontmatter-as-display-desc': '啟用後,使用指定的筆記屬性的值作為筆記連結的顯示文本',
'frontmatter-key': '筆記屬性名',
'frontmatter-key-desc': '用於顯示文本的筆記屬性名(默認:title)',
+ 'enable-display-name-regex': '顯示名稱:正規表示式替換',
+ 'enable-display-name-regex-desc': '啟用後,對複製的標題/筆記連結的顯示文本進行正規表示式查找替換',
+ 'display-name-regex-from': '查找(正則)',
+ 'display-name-regex-from-desc': '用於匹配顯示文本的正規表示式(如 ^\\d+\\.\\s* 可去除開頭的序號)',
+ 'display-name-regex-to': '替換為',
+ 'display-name-regex-to-desc': '替換字符串,支持捕獲組引用如 $1、$2',
}
};
diff --git a/src/linkBuilder.ts b/src/linkBuilder.ts
index 78ba3e8..2f165af 100644
--- a/src/linkBuilder.ts
+++ b/src/linkBuilder.ts
@@ -47,6 +47,9 @@ export interface BuildHeadingLinkOptions {
headingLinkSeparator: string;
strictHeadingMatch?: boolean;
simplifiedHeadingToNoteLink: boolean;
+ enableDisplayNameRegex?: boolean;
+ displayNameRegexFrom?: string;
+ displayNameRegexTo?: string;
}
export interface BuildHeadingLinkResult {
@@ -127,7 +130,7 @@ function formatMarkdownHeadingLink(o: FormatMarkdownHeadingLinkOptions): string
export function buildHeadingLink(options: BuildHeadingLinkOptions): BuildHeadingLinkResult {
const selectedHeading = stripWikiBrackets(options.heading);
- const displayText = computeDisplayText({
+ let displayText = computeDisplayText({
heading: selectedHeading,
filename: options.filename,
frontmatterTitle: options.frontmatterTitle,
@@ -135,6 +138,17 @@ export function buildHeadingLink(options: BuildHeadingLinkOptions): BuildHeading
headingLinkSeparator: options.headingLinkSeparator,
});
+ // 应用正则替换显示名称
+ if (options.enableDisplayNameRegex && options.displayNameRegexFrom) {
+ try {
+ const regex = new RegExp(options.displayNameRegexFrom, 'gm');
+ const replaceTo = options.displayNameRegexTo ?? '';
+ displayText = displayText.replace(regex, replaceTo);
+ } catch (e) {
+ console.warn('[Easy Copy] Invalid display name regex:', e);
+ }
+ }
+
const simplify = shouldSimplifyHeading({
simplifiedHeadingToNoteLink: options.simplifiedHeadingToNoteLink,
useHeadingAsDisplayText: options.useHeadingAsDisplayText,
diff --git a/src/main.ts b/src/main.ts
index d56c67c..bcff772 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -760,6 +760,9 @@ export default class EasyCopy extends Plugin {
headingLinkSeparator: this.settings.headingLinkSeparator,
strictHeadingMatch: this.settings.strictHeadingMatch,
simplifiedHeadingToNoteLink: this.settings.simplifiedHeadingToNoteLink,
+ enableDisplayNameRegex: this.settings.enableDisplayNameRegex,
+ displayNameRegexFrom: this.settings.displayNameRegexFrom,
+ displayNameRegexTo: this.settings.displayNameRegexTo,
});
void navigator.clipboard.writeText(link);
diff --git a/src/settingTab.ts b/src/settingTab.ts
index ad9af4f..d0535c3 100644
--- a/src/settingTab.ts
+++ b/src/settingTab.ts
@@ -477,5 +477,41 @@ export class EasyCopySettingTab extends PluginSettingTab {
void this.plugin.saveSettings();
})));
}
+
+ // 正则替换显示名称
+ specialFormatGroup.addSetting(setting => setting
+ .setName(this.plugin.t('enable-display-name-regex'))
+ .setDesc(this.plugin.t('enable-display-name-regex-desc'))
+ .addToggle(toggle => toggle
+ .setValue(this.plugin.settings.enableDisplayNameRegex ?? false)
+ .onChange( value => {
+ this.plugin.settings.enableDisplayNameRegex = value;
+ void this.plugin.saveSettings();
+ this.display();
+ })));
+
+ if (this.plugin.settings.enableDisplayNameRegex) {
+ specialFormatGroup.addSetting(setting => setting
+ .setName(this.plugin.t('display-name-regex-from'))
+ .setDesc(this.plugin.t('display-name-regex-from-desc'))
+ .addText(text => text
+ .setPlaceholder('e.g. ^\\d+\\.\\s*')
+ .setValue(this.plugin.settings.displayNameRegexFrom ?? '')
+ .onChange( value => {
+ this.plugin.settings.displayNameRegexFrom = value;
+ void this.plugin.saveSettings();
+ })));
+
+ specialFormatGroup.addSetting(setting => setting
+ .setName(this.plugin.t('display-name-regex-to'))
+ .setDesc(this.plugin.t('display-name-regex-to-desc'))
+ .addText(text => text
+ .setPlaceholder('e.g. $1')
+ .setValue(this.plugin.settings.displayNameRegexTo ?? '')
+ .onChange( value => {
+ this.plugin.settings.displayNameRegexTo = value;
+ void this.plugin.saveSettings();
+ })));
+ }
}
}
diff --git a/src/type.ts b/src/type.ts
index c43c634..404b868 100644
--- a/src/type.ts
+++ b/src/type.ts
@@ -73,6 +73,9 @@ export interface EasyCopySettings {
autoBlockDisplayText: boolean; // 自动为 Block 添加显示文本
blockDisplayWordLimit: number; // Block 显示文本英文单词限制(按空格分隔)
blockDisplayCharLimit: number; // Block 显示文本字符限制(非英文语言)
+ enableDisplayNameRegex: boolean; // 是否启用正则替换显示名称
+ displayNameRegexFrom: string; // 正则替换:from 模式
+ displayNameRegexTo: string; // 正则替换:to 内容(支持 $1 等捕获组)
}
export const DEFAULT_SETTINGS: EasyCopySettings = {
@@ -107,4 +110,7 @@ export const DEFAULT_SETTINGS: EasyCopySettings = {
autoBlockDisplayText: true,
blockDisplayWordLimit: 3, // 英文单词限制:3个单词
blockDisplayCharLimit: 5, // 字符限制:5个字符
+ enableDisplayNameRegex: false,
+ displayNameRegexFrom: '',
+ displayNameRegexTo: '',
}
\ No newline at end of file
diff --git a/versions.json b/versions.json
index d1fe0a0..09f85fc 100644
--- a/versions.json
+++ b/versions.json
@@ -21,5 +21,6 @@
"1.6.3": "0.15.0",
"1.6.4": "1.8.7",
"1.6.5": "1.8.7",
- "1.7.0": "1.8.7"
+ "1.7.0": "1.8.7",
+ "1.7.1": "1.8.7"
}