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,31 +2,67 @@ use nu_test_support::fs::Stub;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn extracts_fields_from_the_given_the_pattern() {
Playground::setup("parse_test_1", |dirs, sandbox| {
sandbox.with_files(vec![Stub::FileWithContentToBeTrimmed(
"key_value_separated_arepa_ingredients.txt",
r#"
VAR1=Cheese
VAR2=JonathanParsed
VAR3=NushellSecretIngredient
"#,
)]);
mod simple {
use super::*;
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open key_value_separated_arepa_ingredients.txt
| parse "{Name}={Value}"
| nth 1
| get Value
| echo $it
#[test]
fn extracts_fields_from_the_given_the_pattern() {
Playground::setup("parse_test_1", |dirs, sandbox| {
sandbox.with_files(vec![Stub::FileWithContentToBeTrimmed(
"key_value_separated_arepa_ingredients.txt",
r#"
VAR1=Cheese
VAR2=JonathanParsed
VAR3=NushellSecretIngredient
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open key_value_separated_arepa_ingredients.txt
| lines
| each { echo $it | parse "{Name}={Value}" }
| nth 1
| echo $it.Value
"#
));
assert_eq!(actual.out, "JonathanParsed");
})
}
#[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, "JonathanParsed");
})
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 {

View file

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