title: Bash Regex Pattern Matching: How To Use Variables Inside of Pattern Variable?
body: <p>I'm trying to <strong>a)</strong> scan a string for a pattern match <strong>b)</strong> save the matches to a list <strong>c)</strong> filter the matches from the original string.</p>
  <p>No matter the regex I use, it just won't match. I think the problem is the way I'm using a variable in the regex pattern variable, and/or the way I'm defining [space].</p>
  <h2><strong>Suspected problem code:</strong></h2>
  <pre><code>trig_chars='\s\s' # Double space # Can be numbers, spaces, a-z, A-Z, or special chars.
          
  pat_before_after=&quot;^[^\s]$trig_chars[^\s]&quot; # Any characters before or after trig chars until space or beginning/end of query hit.
      
  if [[ &quot;$accum&quot; =~ &quot;$pat_before_after&quot; ]] ; then  # Trig char found.  
  </code></pre>
  <p>Am I defining $trig_chars right in the  $pat_before_after var?  Am I using the vars correctly in the regex compare statement?</p>
  <h2><strong>More context:</strong></h2>
  <p>This is what I'm trying to do:</p>
  <p><strong>Example:</strong></p>
  <blockquote>
  <p>raw_query='A[space][space] this is a Bcd[space][space] test
  e$F[space][space] query [space][space] G'</p>
  <p>hotstrings=('A' 'Bcd' 'e$F' 'G')</p>
  <p>filtered_query='this is a test query'</p>
  </blockquote>
  <p>From $raw_query get $hotstrings and $filtered_query.</p>
  <h2>Here's how I'm trying to do it:</h2>
  <p>Recursive search through each string character until a match is found.  Remove the match.  And build the filtered query var from the unmatched characters.</p>
  <p>(I suspect this is not the way to do it, but haven't been successful getting tests to pass with other attempts.)</p>
  <h2>Here's the related code in full context:</h2>
  <pre><code>#!/bin/bash
  # Gets hotstrings from raw query.
  # Returns hotstrings and filtered query, with trigger characters and hotstrings removed.
  
  #Global vars
  raw_query='' # User input thru Zenity
  # trig_chars='  ' # Double space
  trig_chars='\s\s' # Double space 
  hotstrings=() # Any chars in raw_query before/after trig chars until space or beginning/end of query hit.
  filtered_query='' # Raw_query with hotstrings &amp; trig chars removed.
  
  pat_before_after=&quot;^[^\s]$trig_chars[^\s]&quot; # Any characters before or after trig chars until space or beginning/end of query hit.
  
  # Scans raw query for trig chars &amp; hotstrings.
  # Filters trig chars &amp; hotstrings from filtered_query var.
  get_hotstrings(){
      # Guard clause edge case, no trigger chars defined.
      if [ &quot;$trig_chars&quot; == &quot;&quot; ]; then 
          filtered_query=&quot;$raw_query&quot;
      return; fi
  
      local scan_text=&quot;$raw_query&quot;
      local accum='' # Used to accumulate unmatched chars.
      filtered_query='' # Blank out filtered query before scan.
  
      while [ &quot;$scan_text&quot; != &quot;&quot; ]; do # Recursive search thru each char.
          local next_char=${scan_text:0:1}
          local accum=&quot;$accum$next_char&quot; 
  
          if [[ &quot;$accum&quot; =~ &quot;$pat_before_after&quot; ]] ; then  # Trig char found.  
  
              local l=${#accum}
              local scan_text=${scan_text:$l} # Remove chars &amp; hotscan_texts from scan_text.
  
              hotstring=${BASH_REMATCH[1]} # Get hotstring from pattern match.
               
              hotstrings+=(&quot;$hotstring&quot;) # Update hotstrings list
              local accum='' # Start new accumulator.
          else
              filtered_query=&quot;$filtered_query$next_char&quot; # Build the filtered query from non-matched chars.
              scan_text=${scan_text:1} # remove char.
          fi
      done
      
  }
  
  
  ################### TESTS ##################
  
  test_messages(){
      #$1=test_name
      #$2=expected result.
      #$3=actual result.
  
      msg=&quot;Test name:$1
      Expected result:$2
      Actual result:$3&quot;
  
      if [ &quot;$2&quot; == &quot;$3&quot; ]; then
          msg2='SUCCESS'
      else
          msg2='FAILED'
      fi
      echo &quot;$msg&quot;
      echo &quot;$msg2&quot;
  }
  
  hotstring_scan_test(){
      #$1=Test name
      #$2=raw query
      #$3=trig chars
      #$4=Expected hotstrings.
      #$5=Expected filtered query.
  
      raw_query=&quot;$2&quot;
      trig_chars=&quot;$3&quot;
      
      get_hotstrings
      r=&quot;${hotstrings[*]}&quot;
      
      msg1=&quot;Test name: $1 
      Raw query: $2 
      Trig chars: $3&quot; 
  
      if [ &quot;$r&quot; == &quot;$4&quot; ]; then
          msg2=&quot;SUCCESS&quot;
      else
          msg2=&quot;Expected hotstring result:$4 
          Actual hotstring result:$r
          FAILED&quot;
      fi
      echo &quot;$msg1&quot;
      echo &quot;$msg2&quot;
      echo &quot;&quot;
  
      msg1=&quot;Filtered query test:
      Filtered query: $filtered_query&quot;
  
      if [ &quot;$filtered_query&quot; == &quot;$5&quot; ]; then
          msg2=&quot;SUCCESS&quot;
      else
          msg2=&quot;Expected result:$5 
          Actual result:$filtered_query 
          FAILED&quot;
      fi
      echo &quot;$msg1&quot;
      echo &quot;$msg2&quot; 
      echo &quot;&quot;
  }
      
  hotstring_scan_tests(){
      local t_name='No trigger chars defined'
      local q='Test query without hotstrings or trigger chars'
      raw_query=&quot;$q&quot;
      local eq='Test query without hotstrings or trigger chars'
      local tc=''
      local eh=''
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
      local t_name='No trigger chars defined'
      local q='Test query without hotstrings or trigger chars'
      raw_query=&quot;$q&quot;
      local eq='Test query without hotstrings or trigger chars'
      local tc='**'
      local eh=''
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
      local t_name='Double space trigger chars'
      local q='  aabc Test   b Query with Hotstrings removed   c'
      raw_query=&quot;$q&quot;
      local eq='Test Query with Hotstrings removed'
      local tc='  '
      local eh='aabc b c'
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
      local t_name='Double space after trigger chars'
      local q='aabc   Test b   Query with Hotstrings removed c  '
      raw_query=&quot;$q&quot;
      local eq='Test Query with Hotstrings removed'
      local tc='  '
      local eh='aabc b c'
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
  
      local t_name='Trigger chars before hotstring'
      local q='**aabc Test **b Query with Hotstrings removed **c'
      raw_query=&quot;$q&quot;
      local eq='Test Query with Hotstrings removed'
      local tc='**'
      local eh='aabc b c'
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
      local t_name='Trigger chars after hotstring'
      local q='aabc** Test b** Query with Hotstrings removed c**'
      raw_query=&quot;$q&quot;
      local eq='Test Query with Hotstrings removed'
      local tc='**'
      local eh='aabc b c'
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
      local t_name='Trigger chars before &amp; after hotstring'
      local q='aabc** Test **B$! Query with Hotstrings removed **c123'
      raw_query=&quot;$q&quot;
      local eq='Test Query with Hotstrings removed'
      local tc='**'
      local eh='aabc B$1! c123'
      hotstring_scan_test &quot;$t_name&quot; &quot;$q&quot; &quot;$tc&quot; &quot;$eh&quot; &quot;$eq&quot;
      filtered_query=''
  
  
  }
  
  performance_test(){
      start=$(($(date +%s%N)/1000000))
  
      for i in {1..10000}; do
          run_all_tests
      done
  
      end=$(($(date +%s%N)/1000000))
      execution_time=$(expr $end - $start)
  
      echo &quot;Execution time in nano seconds: $execution_time&quot;
  }
  
  run_all_tests(){
      set -x
      hotstring_scan_tests
  
  }
  
  run_all_tests
  # performance_test
  </code></pre>