diff --git a/src/lib/parser/shell_expand/mod.rs b/src/lib/parser/shell_expand/mod.rs
index 2104d20de954b27eb7b28255ef6478aa5c3012b9..71bdab105fbba8a108cebdeaae542eed43f3b9c0 100644
--- a/src/lib/parser/shell_expand/mod.rs
+++ b/src/lib/parser/shell_expand/mod.rs
@@ -904,7 +904,7 @@ mod test {
     fn inline_expression() {
         let cases = vec![
             (array!["5"], "$len([0 1 2 3 4])"),
-            (array!["FxOxO"], "$join(@chars(FOO), 'x')"),
+            (array!["FxOxO"], "$join(@chars('FOO') 'x')"),
         ];
         for (expected, input) in cases {
             assert_eq!(expected, expand_string(input, &VariableExpander, false));
diff --git a/src/lib/parser/shell_expand/words/mod.rs b/src/lib/parser/shell_expand/words/mod.rs
index 79d6cfc82cbe08c930c6fd5668592276ab2fdc08..88f974cf24252dbdc3d4537e02d3520ce77fcae1 100644
--- a/src/lib/parser/shell_expand/words/mod.rs
+++ b/src/lib/parser/shell_expand/words/mod.rs
@@ -359,7 +359,12 @@ impl<'a, E: Expander + 'a> WordIterator<'a, E> {
                     let mut depth = 0;
                     while let Some(character) = iterator.next() {
                         match character {
-                            b',' if depth == 0 => {
+                            b'\'' => self.flags ^= Flags::SQUOTE,
+                            b'"' => self.flags ^= Flags::DQUOTE,
+                            b'[' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => depth += 1,
+                            b']' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => depth -= 1,
+                            b' ' if depth == 0
+                                && !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => {
                                 let variable = &self.data[start..self.read];
                                 self.read += 1;
                                 start = self.read;
@@ -486,7 +491,12 @@ impl<'a, E: Expander + 'a> WordIterator<'a, E> {
                     let mut depth = 0;
                     while let Some(character) = iterator.next() {
                         match character {
-                            b',' if depth == 0 => {
+                            b'\'' => self.flags ^= Flags::SQUOTE,
+                            b'"' => self.flags ^= Flags::DQUOTE,
+                            b'[' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => depth += 1,
+                            b']' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => depth -= 1,
+                            b' ' if depth == 0
+                                && !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => {
                                 let variable = &self.data[start..self.read];
                                 self.read += 1;
                                 start = self.read;
diff --git a/src/lib/parser/shell_expand/words/tests.rs b/src/lib/parser/shell_expand/words/tests.rs
index 1c74638c983b59dbc24bb3ae3d80e27464c6ad45..723958e3c08450e73d50457294d1e4a52c81c3cc 100644
--- a/src/lib/parser/shell_expand/words/tests.rs
+++ b/src/lib/parser/shell_expand/words/tests.rs
@@ -17,7 +17,7 @@ fn compare(input: &str, expected: Vec<WordToken>) {
 
 #[test]
 fn string_method() {
-    let input = "$join(array, 'pattern') $join(array, 'pattern')";
+    let input = "$join(array 'pattern') $join(array 'pattern')";
     let expected = vec![
         WordToken::StringMethod(StringMethod {
             method:    "join",