SOURCE

function processHoursText(text) {
    // 步骤1:提取所有时间范围并替换为临时标记,避免被处理
    const rangeRegex = /\d+(\.\d+)?~(\d+(\.\d+)?)(个)?小时/g;
    const ranges = [];
    let tempText = text.replace(rangeRegex, (match) => {
        ranges.push(match);
        return `__RANGE_${ranges.length - 1}__`; // 生成唯一占位符
    });
    
    // 步骤2:处理剩余的单独时间
    const singleTimeRegex = /(?<!~|\d)(\d+(\.\d+)?)(个)?小时(?!~|\d)/g;
    tempText = tempText.replace(singleTimeRegex, (match, numberStr) => {
        const number = parseFloat(numberStr);
        const lower = number - 1;
        const upper = number + 0.5;
        
        // 格式化输出,移除不必要的.0
        const formatNumber = (num) => {
            return num % 1 === 0 ? num.toString() : num.toFixed(1);
        };
        
        return `${formatNumber(lower)}~${formatNumber(upper)}个小时`;
    });
    
    // 步骤3:恢复之前提取的时间范围
    ranges.forEach((range, index) => {
        tempText = tempText.replace(`__RANGE_${index}__`, range);
    });
    return tempText;
}

// 测试用例
let text = "测试文本:3个小时,4.5个小时,2.5~4个小时,4~5.5个小时,6";
console.log("处理前:", text);
text = processHoursText(text);
console.log("处理后:", text);
// 预期:测试文本:2~3.5个小时,3.5~5个小时,2.5~4个小时,4~5.5个小时

// 再次处理测试(关键测试)
text = processHoursText(text);
console.log("再次处理后:", text);
// 预期:与上一次结果完全相同,没有变化

// 新增内容测试
text += "个小时,7.8小时,9~10.5个小时,11个小时";
console.log("新增后:", text);
text = processHoursText(text);
console.log("处理新增后:", text);
// 预期包含:5~6.5个小时,6.8~8.3个小时,9~10.5个小时,10~11.5个小时
console 命令行工具 X clear

                    
>
console