当前位置: 首页 > news >正文

中英文、中英标点及数字按视觉长度分割

--中英文、中英标点及数字按视觉长度分割
unit TextSplitByVisualWidth;

interface

uses
System.SysUtils, System.Classes, System.Character;

type
TVisualTextSplitter = class
public
{ 按视觉宽度分割混合文本
ASourceText: 待分割的源文本(中英/标点/数字混合)
AVisualWidth: 每个片段的目标视觉宽度(中文/全角符=2,英文/半角符=1)
返回值: 分割后的文本片段列表(需手动释放) }
class function SplitByVisualWidth(const ASourceText: string; AVisualWidth: Integer): TStringList;
private
{ 计算单个字符的视觉宽度 }
class function GetCharVisualWidth(const AChar: Char): Integer;
{ 判断是否为全角标点/符号 }
class function IsFullWidthPunctuation(const AChar: Char): Boolean;
end;

implementation

{ TVisualTextSplitter }

class function TVisualTextSplitter.GetCharVisualWidth(const AChar: Char): Integer;
begin
// 1. 中文字符(基本汉字区)→ 2单位
if (AChar >= #$4E00) and (AChar <= #$9FFF) then
Result := 2
// 2. 全角标点/符号 → 2单位
else if IsFullWidthPunctuation(AChar) then
Result := 2
// 3. 英文/数字/半角标点等 → 1单位
else
Result := 1;
end;

class function TVisualTextSplitter.IsFullWidthPunctuation(const AChar: Char): Boolean;
begin
// 覆盖常见全角标点/符号的Unicode范围
Result := (AChar >= #$FF01) and (AChar <= #$FF60) // 全角标点/符号区
or (AChar >= #$3000) and (AChar <= #$303F) // 中文标点/符号区
or (AChar >= #$FFE0) and (AChar <= #$FFEF); // 全角符号(¥、¢等)
end;

class function TVisualTextSplitter.SplitByVisualWidth(const ASourceText: string; AVisualWidth: Integer): TStringList;
var
CurrentWidth: Integer; // 当前累计视觉宽度
CurrentSegment: string; // 当前拼接的文本片段
I: Integer; // 循环变量
CharWidth: Integer; // 当前字符的视觉宽度
begin
Result := TStringList.Create;
try
// 边界处理:目标宽度≤0或源文本为空,直接返回空列表
if (AVisualWidth <= 0) or ASourceText.IsEmpty then
Exit;

CurrentWidth := 0;
CurrentSegment := '';

// 逐字符遍历源文本
for I := 1 to Length(ASourceText) do
begin
CharWidth := GetCharVisualWidth(ASourceText[I]);

// 新增当前字符会超宽度 → 保存当前片段,重置
if (CurrentWidth + CharWidth) > AVisualWidth then
begin
if CurrentSegment <> '' then
Result.Add(CurrentSegment);

CurrentSegment := ASourceText[I];
CurrentWidth := CharWidth;
end
else
begin
// 未超宽度,继续拼接
CurrentSegment := CurrentSegment + ASourceText[I];
CurrentWidth := CurrentWidth + CharWidth;
end;
end;

// 添加最后一个未完成的片段
if CurrentSegment <> '' then
Result.Add(CurrentSegment);
except
Result.Free;
raise; // 抛出异常,让上层处理
end;
end;

end.


--------------------------------调用-----------------------------
procedure TForm1.btnSplitClick(Sender: TObject);
var
SplitResult: TStringList;
I: Integer;
SourceText: string;
TargetWidth: Integer;
begin
// 测试文本(包含中文、英文、数字、全/半角标点)
SourceText := 'Delphi10编程:中文+英文+数字123,全角标点。半角标点,!';
// 指定目标视觉宽度为10
TargetWidth := 10;

// 执行分割
SplitResult := TVisualTextSplitter.SplitByVisualWidth(SourceText, TargetWidth);
try
// 显示分割结果
Memo1.Clear;
Memo1.Lines.Add(Format('源文本:%s', [SourceText]));
Memo1.Lines.Add(Format('目标视觉宽度:%d', [TargetWidth]));
Memo1.Lines.Add('————分割结果————');
for I := 0 to SplitResult.Count - 1 do
Memo1.Lines.Add(Format('片段%d:%s', [I+1, SplitResult[I]]));
finally
SplitResult.Free; // 必须释放,避免内存泄漏
end;
end;

http://www.jsqmd.com/news/322692/

相关文章:

  • 2026简单易用的PPT智能生成工具及实操指南
  • 揭秘电商企业降本60%的SQL优化黄金法则
  • 超轻量图片水印添加工具:13.5KB绿色版,支持自定义内容与位置
  • 告别熬夜做PPT!5款高性价比AI生成工具,效率翻倍不踩坑
  • 考执业医师哪个课程好?小编推荐你选阿虎医考!
  • 爆了!关于2026开年3位程序员接连猝死事件对普通人的启示录一
  • 视频批量智能分割工具:一键自动剪辑与镜头识别教程
  • 考中医执业医师,到底哪个老师讲得好?
  • 告别熬夜做PPT!3款AI一键生成神器,学生党职场人闭眼冲
  • 备课效率翻倍!2026教师专用PPT工具全攻略:传统神器+AI黑科技一网打尽
  • 告别PPT排版焦虑!4个宝藏模板平台,覆盖全场景需求
  • 告别熬夜做PPT!4款宝藏生成工具实测,小白也能秒变设计大神
  • 三维激光扫描与comsol
  • 高低温冲击试验箱哪家质量好?精选厂家对比
  • 备课神器|6款教师专属PPT生成工具,5分钟搞定精美课件!
  • 2026学生党PPT神器推荐:3款AI工具实测横评,告别熬夜赶稿!
  • 备考中医执医考试,我为什么推荐阿虎医考
  • 揭秘!6款宝藏PPT制作工具,适配所有人群,新手也能轻松上手
  • 学生党PPT神器全攻略:免费工具+AI助手,轻松搞定课堂汇报与小组作业
  • 1.29.codeforces div2 C,D 个人题解 - CUC
  • 2025-2026 AI PPT工具实测解析:百度文库PPT全场景能力拆解
  • 2026职场PPT工具天花板推荐:AI赋能+高效出稿,打工人必备指南
  • 2026年A级防火悬挂吸音板厂家权威推荐榜:工程专用/防火阻燃优质品牌全解析
  • 职场PPT神器来袭!打工人告别熬夜做汇报
  • 2026公安心理测评系统哪家靠谱?深度剖析 “星云星空”数智化闭环平台
  • 解锁PPT神器,轻松搞定各类演示制作
  • 告别熬夜做PPT!10款智能生成工具,职场教育人效率翻倍
  • 解锁6款PPT制作神器,轻松打造惊艳课件
  • Ovis-Image:卓越的图像生成模型
  • 2026年耐高压深水测力传感器品牌推荐榜:深水测力传感器哪家好?口碑怎么样?业内权威评测与供应商排名