mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2026-01-20 04:01:06 +00:00
expr: implement regular expressions
This commit is contained in:
parent
eb75085595
commit
9abc3208d3
10 changed files with 318 additions and 221 deletions
|
|
@ -9,6 +9,7 @@ path = "expr.rs"
|
|||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
onig = "1.1"
|
||||
uucore = { path="../uucore" }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
extern crate onig;
|
||||
|
||||
mod tokens;
|
||||
mod syntax_tree;
|
||||
|
|
@ -95,9 +96,9 @@ separates increasing precedence groups. EXPRESSION may be:
|
|||
ARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2
|
||||
ARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2
|
||||
|
||||
STRING : REGEXP [NOT IMPLEMENTED] anchored pattern match of REGEXP in STRING
|
||||
STRING : REGEXP anchored pattern match of REGEXP in STRING
|
||||
|
||||
match STRING REGEXP [NOT IMPLEMENTED] same as STRING : REGEXP
|
||||
match STRING REGEXP same as STRING : REGEXP
|
||||
substr STRING POS LENGTH substring of STRING, POS counted from 1
|
||||
index STRING CHARS index in STRING where any CHARS is found, or 0
|
||||
length STRING length of STRING
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
//!
|
||||
|
||||
use tokens::{Token};
|
||||
use onig::{Regex, Syntax, REGEX_OPTION_NONE};
|
||||
|
||||
type TokenStack = Vec<(usize, Token)>;
|
||||
pub type OperandsList = Vec< Box<ASTNode> >;
|
||||
|
|
@ -105,6 +106,7 @@ impl ASTNode {
|
|||
),
|
||||
"|" => infix_operator_or(&operand_values),
|
||||
"&" => infix_operator_and(&operand_values),
|
||||
":" | "match" => operator_match(&operand_values),
|
||||
"length" => prefix_operator_length( &operand_values ),
|
||||
"index" => prefix_operator_index( &operand_values ),
|
||||
"substr" => prefix_operator_substr( &operand_values ),
|
||||
|
|
@ -350,6 +352,25 @@ fn infix_operator_and( values: &Vec<String> ) -> Result<String, String> {
|
|||
}
|
||||
}
|
||||
|
||||
fn operator_match(values: &Vec<String>) -> Result<String, String> {
|
||||
assert!(values.len() == 2);
|
||||
let re = match Regex::with_options(&values[1], REGEX_OPTION_NONE, Syntax::grep()) {
|
||||
Ok(m) => m,
|
||||
Err(err) => return Err(err.description().to_string())
|
||||
};
|
||||
if re.captures_len() > 0 {
|
||||
Ok(match re.captures(&values[0]) {
|
||||
Some(captures) => captures.at(1).unwrap().to_string(),
|
||||
None => "".to_string()
|
||||
})
|
||||
} else {
|
||||
Ok(match re.find(&values[0]) {
|
||||
Some((start, end)) => (end - start).to_string(),
|
||||
None => "0".to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn prefix_operator_length( values: &Vec<String> ) -> Result<String, String> {
|
||||
assert!( values.len() == 1 );
|
||||
Ok( values[0].len().to_string() )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue