title: Regex to extract expressions from input string
body: <p>I'm trying to use a regular expression to extract expressions in the format of "operand operator operand" from a input string. The operands may be any single words or quoted phrases and the operator between operands will be the tilde sign followed by a numeral. The expression might occur n number of times within the input string. What's wrong in my regex?</p>
  
  <pre><code>package test;
  
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  public class ExpressionExtractor {
  
      private static final String operator = "\\s+\\~{1}\\d+\\s+";
      private static final String quotedWords = "[\"|'|“][A-Za-zÀ-ü0-9\\\\.\\/\\-,\\*\\s]+[\"|'|“]";
      private static final String singleWords = "[A-Za-zÀ-ü0-9\\\\.\\/\\-,\\*]+";
      private static final String operand = quotedWords+"|"+singleWords;
      private static final Pattern expressionPattern = Pattern.compile("("+operand + operator +operand+")");
      private static final Pattern operatorPattern = Pattern.compile(operator);
  
      public static Matcher evaluateExpression(String input) {
          return expressionPattern.matcher(input);
      }
  }
  </code></pre>
  
  <p>A test case with the expected results:</p>
  
  <pre><code>package test;
  
  import static org.junit.Assert.assertEquals;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.regex.Matcher;
  
  import org.junit.Test;
  
  public class ExpressionExtractorUnitTest {
  
      @Test
      public void testExpressionExtractor() {
          assertEquals(Arrays.asList("firstWord ~20 secondWord"), find("any word firstWord ~20 secondWord one more word"));
          assertEquals(Arrays.asList("mother-in-law ~8 long-Word"), find("start of sentence mother-in-law ~8 long-Word one sentence"));
          assertEquals(Arrays.asList("firstWord ~7 secondWord", "word ~8 \"complex expression\""), 
                  find("more complex expression firstWord ~7 secondWord with another word ~8 \"complex expression\" continued"));
      }
  
      private List&lt;String&gt; find(String expression) {
          Matcher matcher = ExpressionExtractor.evaluateExpression(expression);
          List&lt;String&gt; tokens = new ArrayList&lt;&gt;();
          while (matcher.find()) {
              tokens.add(matcher.group());
          }
          return tokens;
      }
  }
  </code></pre>