目录

  • 前言
  • 字符串进阶处理
  • 模板字符串
  • 字符串大小写转换
  • 结束语

前言

在 HarmonyOS 的声明式 UI 框架 ArkUI 中,字符串是连接逻辑层与视图层的核心桥梁。无论是从后端 API 接收的 JSON 数据、用户输入的表单内容,还是本地存储的配置项,最终大多以字符串形式参与渲染、校验或持久化,但是许多开发者仅停留在 split、replace、indexOf等基础方法的使用层面,忽略了 性能陷阱、编码安全、国际化适配 等高阶问题。作为开发者都清楚字符串不仅用于用户界面显示,还用于数据传输、日志记录和本地化等多种场景,在HarmonyOS应用开发中也是至关重要的,个人觉得掌握字符串的操作和管理对于开发高效、易维护的应用也至关重要。那么本文就来详细分享一下关于在HarmonyOS开发中字符串相关的内容,方便大家了解和学习使用。

字符串进阶处理

接下来就来分享关于字符串深度处理的操作,这里罗列几个常用的日常开发场景来分享。

1、关于时间的处理

比如要把字符串“2024-11-30 14:30:23”处理为“2024年11月30日 14时30分23秒”,具体示例代码如下所示:

var str = "2024-11-30 14:30:23";
//方法一
var time = str.split(" ");
console.log(time) //["2024-11-30", "14:30:23"]
var timeLeft = time[0];
var timeRight = time[1];
var ary1 = timeLeft.split("-"); // ["2024", "11", "30"]
var ary2 = timeRight.split(":");// ["14", "30", "23"]
var res = ary1[0] + "年" + ary1[1] + "月" + ary1[2] + "日" + " " + ary2[0] + "时" + ary2[1] + "分" + ary2[2] + "秒"
console.log(res) //"2024年11月30日 14时30分23秒"

//方法二
//补零
function zeroFill(number){
    return number < 10 ? "0" + number : number;
}
var ss = zeroFill(11);
var res2 = zeroFill(ary1[0])+"年"+zeroFill(ary1[1])+"月"+zeroFill(ary1[2])+"日"+" "+zeroFill(ary2[0])+"时"+zeroFill(ary2[1])+"分"+zeroFill(ary2[2])+"秒"
//"2024年11月30日 14时30分23秒"

💡 工程化建议
虽然上述方法可行,但在生产环境中,强烈推荐使用 HarmonyOS 内置的 @ohos/intl 模块进行本地化时间格式化,避免硬编码中文单位,提升国际化能力:

import { util } from '@kit.ArkTS';
const date = new Date("2024-11-30T14:30:23");
const formatter = util.getDateTimeFormatter({
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
});
console.log(formatter.format(date)); // 自动适配系统语言

另外手动字符串拼接在高频调用时性能较差,可考虑使用 模板字符串或预编译函数。

2、关于问号参数处理

再来分享一个关于网络链接中问号参数处理的情况,这里是关于queryURLParams的 问号参数处理,具体示例代码如下所示:

/*
处理方法
var str ="https://www.baidu.com?name=sanzhanggui&age=18&id=666";
{ name:"sanzhanggui", age:18, id:666 }
*/
  function urlParams(str){
      var obj={};
      var paramsStr=str.split("?")[1];
      if(paramsStr){
          //[name=sanzhanggui,age=18,id=666]
          var paramsArray=paramsStr.split("&");
          for(var i=0;i<paramsArray.length;i++){
                //name=sanzhanggui
               var item=paramsArray[i];
               //[name,sanzhanggui]
               var itemArray=item.split("=");
               obj[itemArray[0]]=itemArray[1];
          }
      }
      return obj;
  }
  var str ="https://www.baidu.com?name=sanzhanggui&age=18&id=666";
  var result= urlParams(str);

⚠️ 安全与健壮性补充
上述实现存在两个潜在问题:

  1. 未解码 URL 编码:若参数值包含 %E4%B8%AD%E6%96%87(中文),需调用 decodeURIComponent();
  2. 键值对分割不严谨:split("=") 在值本身含 = 时会出错(如 token=a=b=c)。

改进版

function parseQuery(url: string): Record<string, string> {
  const obj: Record<string, string> = {};
  const search = url.split('?')[1];
  if (!search) return obj;
  search.split('&').forEach(pair => {
    const [key, ...rest] = pair.split('=');
    if (key) {
      obj[decodeURIComponent(key)] = decodeURIComponent(rest.join('=') || '');
    }
  });
  return obj;
}

3、字符串转换处理

这里分享一个比较常用的场景,比如在传递的参数中包含字符串,就转换成数字;但是如果字符串是非有效的数字,那就直接忽略。具体的示例代码如下所示:

//处理方法一
function fun(){
    var total=0;
    for(var i=0;i<arguments.length;i++){
        var item=Number(arguments[i]);
        isNaN(item)?0:total+=item
    }
    return total;
}
//处理方法二
function fun(...arg){
    return eval(arg.filter((item)=>!isNaN(item)).join("+"))
}
//具体使用的地方
var result=fun(1,2,3,"3","3px");

🚫 严重警告
绝对不要在生产代码中使用eval()!它会执行任意 JavaScript 代码,带来严重的安全漏洞(如代码注入)和性能问题安全替代方案

function sumValidNumbers(...args: any[]): number {
  return args
    .map(arg => Number(arg))
    .filter(num => !isNaN(num))
    .reduce((sum, num) => sum + num, 0);
}

4、字符串使用场景:邮箱校验

接下来再来分享一个关于实际开发中必遇到的使用场景,关于邮箱是否输入正确的校验处理,具体示例代码如下所示:

   void main(String[] args) {
       let email:String = "example@email.com";
       let regex:RegExp = "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(email);
        if (matcher.matches()) {
            System.out.println("邮箱格式正确");
        } else {
            System.out.println("邮箱格式错误");
        }
    }

❗ 语言混用修正
此段代码混合了 Java 和 TypeScript 语法。在 ArkTS 中,应使用纯 TS 写法:

const email = "example@email.com";
const regex = /^[\w.-]+@[\w.-]+\.\w+$/;
if (regex.test(email)) {
  console.log("邮箱格式正确");
} else {
  console.log("邮箱格式错误");
}

注意:完整邮箱校验极其复杂,上述正则仅作基础验证。生产环境建议结合后端校验或使用专用库。

5、字符串使用场景:手机号校验

手机号校验也是日常开发中必备功能,具体示例如下所示:

import promptAction from '@ohos.promptAction';
 
export class RegExpUtils {
  // 手机号正则字符串
  PHONE: string = '((1[3|4|5|7|8][0-9]{9})$)'
  
 // 手机号正则
  checkPhone(phone: string): boolean {
    if (phone.length === 0) {
      promptAction.showToast({
        message: '请输入手机号码',
        bottom: 100,
        duration: 1000
      })
      return false
    }
    let reg: RegExp = new RegExp(this.PHONE);
 
    if (!reg.test(phone)) {
      promptAction.showToast({
        message: '请输入正确格式 11 位的手机号码!',
        bottom: 100,
        duration: 1000
      })
      return false
    }
    return true
  }
}

//具体使用
 
 if (!this.regExpUtils.checkPhone(this.phone ?? "")) {
    return
 }

🔧 正则优化:原正则 (1[3|4|5|7|8][0-9]{9})$ 中的 [3|4|5|7|8] 错误地包含了 | 字符。正确写法应为 (1[34578]\d{9})$。更厉害的版本(支持 19 开头新号段):

PHONE = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;

6、字符串使用场景:身份证校验

身份证校验也是日常开发中必备功能,具体示例如下所示:

import promptAction from '@ohos.promptAction';
 
export class RegExpUtils {
  // 身份证正则字符串
  DATE: string = '((0[1-9])|(10|11|12))((0[1-9])|(1[0-9])|(2[0-9])|(30|31))'
  CARD: string = '^(([1-9]{1})([0-9]{5})(18|19|20)[0-9]{2}(' + this.DATE + '))([0-9]{4})|([0-9]{3}(x|X))$'
 
  /*
   * 身份证正则
   * */
  checkIdCard(card: string): boolean {
    if (card.length === 0) {
      promptAction.showToast({
        message: '请输入身份证号码',
        bottom: 100,
        duration: 1000
      })
      return false
    }
    let reg = RegExp(this.CARD);
    if (card.length != 18 || !reg.test(card)) {
      promptAction.showToast({
        message: '请输入正确身份证号码',
        bottom: 100,
        duration: 1000
      })
      return false
    }
    return true
  }
}

//具体使用
 if (!this.regExpUtils.checkIdCard(this.cardId ?? "")) {
     return
  }     

📌 重要提醒
身份证校验不能仅依赖正则!必须验证最后一位校验码(通过前17位计算得出)。建议使用成熟库 (如 id-validator)或调用公安接口。

模板字符串

关于模版字符串,往往用在需要拼接字符串的地方,以及拼接变量的时候。
作用: 拼接字符串和变量
写法: ${变量}用反引号包裹
具体示例:

let name = 'sanzhanggui'
console.log('',`我的名字${name}`)

🌟 高级用法扩展

  • 多行字符串:无需 \n,直接换行。
    const sql = `
      SELECT * FROM users
      WHERE name = '${name}'
    `;
    
  • 嵌套表达式
    console.log(`明天是${new Date(Date.now() + 86400000).toLocaleDateString()}`);
    
  • 标签模板(Tagged Templates):用于安全转义(防 XSS)。
    function safeHtml(strings: TemplateStringsArray, ...values: any[]) {
      const escape = (s: string) => s.replace(/[<>&]/g, m => ({'<':'&lt;','>':'&gt;','&':'&amp;'}[m]!));
      return strings[0] + values.map((v, i) => escape(String(v)) + strings[i+1]).join('');
    }
    const html = safeHtml`<div>Hello, ${userInput}</div>`; // 自动转义
    

字符串大小写转换

实际开发中,会在某些场景下,需要对字符串进行大小写的转换,比如银行类app使用的商户号,需要把字母转换为大写。这里分享一个示例:

let string = "hello, world!";
let upper = string.toUpperCase(); // "HELLO, WORLD!" 转换为大写
let lower = string.toLowerCase(); // "hello, world!" 转换为小写

🌍 国际化注意
toUpperCase() 和 toLowerCase() 是基于英语 locale 的。在土耳其等语言中,'i'.toUpperCase() 应为 'İ'(带点的大写 I),而非 'I'。
若需国际化支持,应使用:

'i'.toLocaleUpperCase('tr-TR'); // "İ"

结束语

上面关于HarmonyOS开发中字符串深度专辑的使用介绍,可以看到字符串处理是HarmonyOS开发中的一项基础且重要技能。熟练掌握字符串的基本操作、格式化、本地化和性能优化,开发者可以很好的开发出出更加健壮、高效和易维护的代码,而且通过合理管理字符串资源、熟练使用字符串操作函数以及在用户交互中合理使用字符串,可以大幅提升应用的用户体验和国际化水平。希望本文能帮助大家在鸿蒙开发中更好地处理字符串,构建出更加出色的应用。让每一行字符串代码,都成为用户体验的加分项!

 

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐