Improve the simplified parse form. (#1875)

This commit is contained in:
Jason Gedge 2020-05-25 14:19:49 -04:00 committed by GitHub
parent 07996ea93d
commit cb6ccc3c5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 28 deletions

View File

@ -2,6 +2,9 @@ use nu_test_support::fs::Stub;
use nu_test_support::playground::Playground; use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline}; use nu_test_support::{nu, pipeline};
mod simple {
use super::*;
#[test] #[test]
fn extracts_fields_from_the_given_the_pattern() { fn extracts_fields_from_the_given_the_pattern() {
Playground::setup("parse_test_1", |dirs, sandbox| { Playground::setup("parse_test_1", |dirs, sandbox| {
@ -18,10 +21,10 @@ fn extracts_fields_from_the_given_the_pattern() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open key_value_separated_arepa_ingredients.txt open key_value_separated_arepa_ingredients.txt
| parse "{Name}={Value}" | lines
| each { echo $it | parse "{Name}={Value}" }
| nth 1 | nth 1
| get Value | echo $it.Value
| echo $it
"# "#
)); ));
@ -29,6 +32,39 @@ fn extracts_fields_from_the_given_the_pattern() {
}) })
} }
#[test]
fn double_open_curly_evalutes_to_a_single_curly() {
Playground::setup("parse_test_regex_2", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "{abc}123"
| parse "{{abc}{name}"
| echo $it.name
"#
));
assert_eq!(actual.out, "123");
})
}
#[test]
fn properly_escapes_text() {
Playground::setup("parse_test_regex_3", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "(abc)123"
| parse "(abc){name}"
| echo $it.name
"#
));
assert_eq!(actual.out, "123");
})
}
}
mod regex { mod regex {
use super::*; use super::*;

View File

@ -6,7 +6,7 @@ use nu_protocol::{
}; };
use crate::{ColumnNames, Parse}; use crate::{ColumnNames, Parse};
use regex::Regex; use regex::{self, Regex};
impl Plugin for Parse { impl Plugin for Parse {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
@ -125,14 +125,19 @@ fn parse(input: &str) -> Vec<ParseCommand> {
let mut output = vec![]; let mut output = vec![];
//let mut loop_input = input; //let mut loop_input = input;
let mut loop_input = input.chars(); let mut loop_input = input.chars().peekable();
loop { loop {
let mut before = String::new(); let mut before = String::new();
while let Some(c) = loop_input.next() { while let Some(c) = loop_input.next() {
if c == '{' { if c == '{' {
// If '{{', still creating a plaintext parse command, but just for a single '{' char
if loop_input.peek() == Some(&'{') {
let _ = loop_input.next();
} else {
break; break;
} }
}
before.push(c); before.push(c);
} }
@ -188,19 +193,21 @@ impl From<&Regex> for ColumnNames {
} }
fn build_regex(commands: &[ParseCommand]) -> String { fn build_regex(commands: &[ParseCommand]) -> String {
let mut output = String::new(); let mut output = "(?s)\\A".to_string();
for command in commands { for command in commands {
match command { match command {
ParseCommand::Text(s) => { ParseCommand::Text(s) => {
output.push_str(&s.replace("(", "\\(")); output.push_str(&regex::escape(&s));
} }
ParseCommand::Column(_) => { ParseCommand::Column(_) => {
output.push_str("(.*)"); output.push_str("(.*?)");
} }
} }
} }
output.push_str("\\z");
output output
} }