Rust ANSI解析库ansi-parser的使用:高效处理终端ANSI转义序列和颜色代码

Rust ANSI解析库ansi-parser的使用:高效处理终端ANSI转义序列和颜色代码

ansi-parser是一个用于解析ANSI转义序列的Rust库,它通过类似pulldown的解析器实现,将ANSI序列转换为枚举类型并在每个存在ANSI序列的位置分割字符串。

使用示例

以下是基础使用示例代码:

use ansi_parser::{Output, AnsiParser};
use ansi_parser::AnsiSequence;

fn main() {
    // 解析字符串中的前两个块
    // 这种方式允许你迭代返回的元素
    // 解析器只持有数据的引用,因此不需要分配内存
    let parsed: Vec<Output> = "This is \u{1b}[3Asome text!"
        .ansi_parse()
        .take(2)
        .collect();

    assert_eq!(
        vec![
            Output::TextBlock("This is "),
            Output::Escape(AnsiSequence::CursorUp(3))
        ],
        parsed
    );

    for block in parsed.into_iter() {
        match block {
            Output::TextBlock(text) => println!("{}", text),
            Output::Escape(seq)     => println!("{}", seq)
        }
    }
}

完整示例demo

下面是一个更完整的示例,展示如何处理包含颜色代码和光标移动的ANSI序列:

use ansi_parser::{Output, AnsiParser};
use ansi_parser::AnsiSequence;

fn main() {
    // 包含颜色代码和光标移动的ANSI字符串
    // \u{1b}[31m 设置红色文本
    // \u{1b}[0m 重置文本样式
    // \u{1b}[32;1m 设置粗体绿色文本
    // \u{1b}[3A 光标上移3行
    let ansi_string = "\u{1b}[31mRed Text\u{1b}[0m followed by \u{1b}[32;1mBold Green\u{1b}[0m and \u{1b}[3Acursor up 3 lines";
    
    // 解析整个字符串
    let parsed: Vec<Output> = ansi_string.ansi_parse().collect();
    
    println!("解析后的块:");
    for (i, block) in parsed.iter().enumerate() {
        println!("块 {}:", i);
        match block {
            Output::TextBlock(text) => println!("  文本: '{}'", text),
            Output::Escape(seq) => match seq {
                AnsiSequence::SetGraphicsMode(params) => {
                    println!("  图形模式参数: {:?}", params)
                },
                AnsiSequence::CursorUp(lines) => {
                    println!("  光标上移 {} 行", lines)
                },
                _ => println!("  其他ANSI序列: {:?}", seq),
            }
        }
    }
    
    // 重构原始ANSI字符串
    let reconstructed: String = parsed.iter().map(|block| match block {
        Output::TextBlock(text) => text.to_string(),
        Output::Escape(seq) => seq.to_string(),
    }).collect();
    
    println!("\n重构后的字符串: {}", reconstructed);
}

no_std支持

ansi-parser支持no_std环境,只需在Cargo.toml中禁用std特性即可。

安装

将以下内容添加到你的Cargo.toml中:

[dependencies]
ansi-parser = "0.9.1"

或者运行以下命令:

cargo add ansi-parser

1 回复

Rust ANSI解析库 ansi-parser 使用指南

ansi-parser 是一个用于解析和处理ANSI转义序列的Rust库,特别适合处理终端输出中的颜色代码、光标控制等ANSI序列。

主要功能

  • 解析ANSI转义序列
  • 提取纯文本内容
  • 处理颜色代码(前景色和背景色)
  • 支持多种ANSI序列类型

安装

Cargo.toml中添加依赖:

[dependencies]
ansi-parser = "0.9"

基本使用方法

1. 解析ANSI文本

use ansi_parser::AnsiParser;
use ansi_parser::Output;

let text = "\x1b[31mHello\x1b[0m \x1b[32;1mWorld\x1b[0m";
let parsed = text.ansi_parse();

for block in parsed.into_iter() {
    match block {
        Output::TextBlock(text) => println!("Text: {}", text),
        Output::Escape(esc) => println!("Escape: {:?}", esc),
    }
}

2. 提取纯文本

use ansi_parser::AnsiParser;

let colored_text = "\x1b[31mError\x1b[0m: Something went wrong";
let plain_text = colored_text.ansi_strip();

println!("{}", plain_text); // 输出: "Error: Something went wrong"

3. 处理颜色代码

use ansi_parser::{AnsiParser, AnsiSequence};

let text = "\x1b[31mRed\x1b[0m and \x1b[32mGreen\x1b[0m";
let parsed = text.ansi_parse();

for block in parsed {
    if let Output::Escape(AnsiSequence::SetGraphicsMode(params)) = block {
        if params[0] == 31 {
            println!("Found red color code");
        }
    }
}

高级用法

自定义ANSI序列处理

use ansi_parser::{AnsiParser, Output, AnsiSequence};

fn process_ansi(text: &str) -> String {
    let mut result = String::new();
    let parsed = text.ansi_parse();
    
    for block in parsed {
        match block {
            Output::TextBlock(t) => result.push_str(t),
            Output::Escape(AnsiSequence::SetGraphicsMode(params)) => {
                // 自定义颜色处理逻辑
                if params.contains(&31) {
                    result.push_str("[RED]");
                } else if params.contains(&32) {
                    result.push_str("[GREEN]");
                }
            }
            _ => {} // 忽略其他ANSI序列
        }
    }
    
    result
}

let output = process_ansi("\x1b[31mAlert\x1b[0m: \x1b[32mOK\x1b[0m");
println!("{}", output); // 输出: "[RED]Alert: [GREEN]OK"

处理光标控制序列

use ansi_parser::{AnsiParser, Output, AnsiSequence};

let text = "Normal\x1b[2KText after clear line";
let parsed = text.ansi_parse();

for block in parsed {
    match block {
        Output::Escape(AnsiSequence::EraseInLine(_)) => {
            println!("Found line erase command");
        }
        _ => {}
    }
}

性能提示

ansi-parser 是为高效处理而设计的,但以下方法可以进一步提高性能:

  1. 重用解析结果而不是重复解析
  2. 对长文本使用流式处理
  3. 只解析需要的ANSI序列类型

实际应用场景

  • 终端日志分析工具
  • CLI应用的输出处理
  • 终端模拟器开发
  • 彩色文本处理工具

ansi-parser 提供了灵活的方式来处理ANSI转义序列,使得在Rust中处理终端输出变得更加简单高效。

完整示例

下面是一个结合了基本和高级用法的完整示例:

use ansi_parser::{AnsiParser, Output, AnsiSequence};

fn main() {
    // 示例1:解析ANSI文本
    let colored_text = "\x1b[31mHello\x1b[0m \x1b[32;1mWorld\x1b[0m";
    println!("解析ANSI文本:");
    let parsed = colored_text.ansi_parse();
    for block in parsed {
        match block {
            Output::TextBlock(text) => println!("文本块: {}", text),
            Output::Escape(esc) => println!("转义序列: {:?}", esc),
        }
    }

    // 示例2:提取纯文本
    println!("\n提取纯文本:");
    let plain_text = colored_text.ansi_strip();
    println!("{}", plain_text);

    // 示例3:自定义处理
    println!("\n自定义ANSI处理:");
    let processed = process_custom_ansi("\x1b[31mError\x1b[0m: \x1b[32mSuccess\x1b[0m");
    println!("{}", processed);
}

fn process_custom_ansi(text: &str) -> String {
    let mut result = String::new();
    let parsed = text.ansi_parse();
    
    for block in parsed {
        match block {
            Output::TextBlock(t) => result.push_str(t),
            Output::Escape(AnsiSequence::SetGraphicsMode(params)) => {
                // 自定义颜色标记
                if params.contains(&31) {
                    result.push_str("[错误]");
                } else if params.contains(&32) {
                    result.push_str("[成功]");
                }
            }
            _ => {}
        }
    }
    
    result
}

这个完整示例展示了:

  1. 如何解析包含ANSI颜色代码的文本
  2. 如何提取纯文本内容
  3. 如何自定义处理ANSI序列(将颜色代码转换为自定义标记)
回到顶部