Skip to content

Instantly share code, notes, and snippets.

@2xsaiko
Last active August 13, 2018 18:52
Show Gist options
  • Save 2xsaiko/669e658f1df58fb92c783d357ce215df to your computer and use it in GitHub Desktop.
Save 2xsaiko/669e658f1df58fb92c783d357ce215df to your computer and use it in GitHub Desktop.
string splitter
import java.util.ArrayList;
import java.util.List;
public class StrParse {
public static List<String> qsplit(String s) {
List<String> list = new ArrayList<>();
int quote = 0;
boolean esc = false;
StringBuilder current = new StringBuilder();
for (char c : s.toCharArray()) {
switch (quote) {
case 0:
if (esc) {
current.append(c);
esc = false;
} else switch (c) {
case '"':
quote = 1;
break;
case '\'':
quote = 2;
break;
case '\\':
esc = true;
break;
case ' ':
case '\n':
list.add(current.toString());
current = new StringBuilder();
break;
default:
current.append(c);
}
case 1:
if (esc) {
current.append(c);
esc = false;
} else switch (c) {
case '\\':
esc = true;
break;
case '"':
quote = 0;
break;
default:
current.append(c);
}
case 2:
switch (c) {
case '\'':
quote = 0;
break;
default:
current.append(c);
}
}
}
if (!current.toString().matches("\\s*")) list.add(current.toString());
return list;
}
}
fun String.qsplit(): List<String> {
@Suppress("LocalVariableName")
val Quote = object {
val none = 0
val double = 1
val single = 2
}
var list: List<String> = emptyList()
var quote = Quote.none
var esc = false
var current = ""
this.forEach { c ->
when (quote) {
Quote.none -> {
when {
esc -> {
current += c
esc = false
}
c == '"' -> quote = Quote.double
c == '\'' -> quote = Quote.single
c == '\\' -> esc = true
c in setOf(' ', '\n') -> {
list += current
current = ""
}
else -> current += c
}
}
Quote.double -> {
when {
esc -> {
current += c
esc = false
}
c == '\\' -> esc = true
c == '"' -> quote = Quote.none
else -> current += c
}
}
Quote.single -> {
when (c) {
'\'' -> quote = Quote.none
else -> current += c
}
}
}
}
if (current.isNotBlank()) list += current
return list
}
pub fn split_respecting_quotes(s: &str) -> Result<Vec<String>, SplitError> {
#[derive(PartialEq)]
enum Quote {
None,
Double,
Single,
}
let mut result = Vec::new();
let mut quote = Quote::None;
let mut esc = false;
let mut current = String::new();
for c in s.chars() {
match quote {
Quote::None => {
if esc {
current.push(c);
esc = false;
continue;
}
match c {
'"' => quote = Quote::Double,
'\'' => quote = Quote::Single,
'\\' => esc = true,
' ' | '\n' => {
result.push(current);
current = String::new();
}
_ => current.push(c),
}
}
Quote::Double => {
if esc {
current.push(c);
esc = false;
continue;
}
match c {
'"' => quote = Quote::None,
'\\' => esc = true,
_ => current.push(c),
}
}
Quote::Single => {
match c {
'\'' => quote = Quote::None,
_ => current.push(c),
}
}
}
}
if !current.is_empty() {
result.push(current);
}
if quote != Quote::None {
Err(SplitError::MismatchedQuotes)
} else {
Ok(result)
}
}
#[derive(Debug, PartialEq)]
pub enum SplitError {
MismatchedQuotes,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment