【发布时间】:2022-01-18 14:03:56
【问题描述】:
我正在尝试 a) 扫描字符串以查找模式匹配 b) 将匹配项保存到列表 c) 过滤匹配原始字符串。
无论我使用什么正则表达式,它都不会匹配。我认为问题在于我在正则表达式模式变量中使用变量的方式,和/或我定义 [space] 的方式。
疑似问题代码:
trig_chars='\s\s' # Double space # Can be numbers, spaces, a-z, A-Z, or special chars.
pat_before_after="^[^\s]$trig_chars[^\s]" # Any characters before or after trig chars until space or beginning/end of query hit.
if [[ "$accum" =~ "$pat_before_after" ]] ; then # Trig char found.
我是否在 $pat_before_after 变量中定义了 $trig_chars?我是否在正则表达式比较语句中正确使用了变量?
更多上下文:
这就是我想要做的:
示例:
raw_query='A[space][space] 这是一个 Bcd[space][space] 测试 e$F[空格][空格]查询[空格][空格] G'
hotstrings=('A' 'Bcd' 'e$F' 'G')
filtered_query='这是一个测试查询'
从 $raw_query 获取 $hotstrings 和 $filtered_query。
这是我的尝试:
递归搜索每个字符串字符,直到找到匹配项。删除匹配。并根据不匹配的字符构建过滤后的查询变量。
(我怀疑这不是这样做的方法,但没有成功通过其他尝试使测试通过。)
这是完整上下文中的相关代码:
#!/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 & trig chars removed.
pat_before_after="^[^\s]$trig_chars[^\s]" # Any characters before or after trig chars until space or beginning/end of query hit.
# Scans raw query for trig chars & hotstrings.
# Filters trig chars & hotstrings from filtered_query var.
get_hotstrings(){
# Guard clause edge case, no trigger chars defined.
if [ "$trig_chars" == "" ]; then
filtered_query="$raw_query"
return; fi
local scan_text="$raw_query"
local accum='' # Used to accumulate unmatched chars.
filtered_query='' # Blank out filtered query before scan.
while [ "$scan_text" != "" ]; do # Recursive search thru each char.
local next_char=${scan_text:0:1}
local accum="$accum$next_char"
if [[ "$accum" =~ "$pat_before_after" ]] ; then # Trig char found.
local l=${#accum}
local scan_text=${scan_text:$l} # Remove chars & hotscan_texts from scan_text.
hotstring=${BASH_REMATCH[1]} # Get hotstring from pattern match.
hotstrings+=("$hotstring") # Update hotstrings list
local accum='' # Start new accumulator.
else
filtered_query="$filtered_query$next_char" # 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="Test name:$1
Expected result:$2
Actual result:$3"
if [ "$2" == "$3" ]; then
msg2='SUCCESS'
else
msg2='FAILED'
fi
echo "$msg"
echo "$msg2"
}
hotstring_scan_test(){
#$1=Test name
#$2=raw query
#$3=trig chars
#$4=Expected hotstrings.
#$5=Expected filtered query.
raw_query="$2"
trig_chars="$3"
get_hotstrings
r="${hotstrings[*]}"
msg1="Test name: $1
Raw query: $2
Trig chars: $3"
if [ "$r" == "$4" ]; then
msg2="SUCCESS"
else
msg2="Expected hotstring result:$4
Actual hotstring result:$r
FAILED"
fi
echo "$msg1"
echo "$msg2"
echo ""
msg1="Filtered query test:
Filtered query: $filtered_query"
if [ "$filtered_query" == "$5" ]; then
msg2="SUCCESS"
else
msg2="Expected result:$5
Actual result:$filtered_query
FAILED"
fi
echo "$msg1"
echo "$msg2"
echo ""
}
hotstring_scan_tests(){
local t_name='No trigger chars defined'
local q='Test query without hotstrings or trigger chars'
raw_query="$q"
local eq='Test query without hotstrings or trigger chars'
local tc=''
local eh=''
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='No trigger chars defined'
local q='Test query without hotstrings or trigger chars'
raw_query="$q"
local eq='Test query without hotstrings or trigger chars'
local tc='**'
local eh=''
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='Double space trigger chars'
local q=' aabc Test b Query with Hotstrings removed c'
raw_query="$q"
local eq='Test Query with Hotstrings removed'
local tc=' '
local eh='aabc b c'
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='Double space after trigger chars'
local q='aabc Test b Query with Hotstrings removed c '
raw_query="$q"
local eq='Test Query with Hotstrings removed'
local tc=' '
local eh='aabc b c'
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='Trigger chars before hotstring'
local q='**aabc Test **b Query with Hotstrings removed **c'
raw_query="$q"
local eq='Test Query with Hotstrings removed'
local tc='**'
local eh='aabc b c'
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='Trigger chars after hotstring'
local q='aabc** Test b** Query with Hotstrings removed c**'
raw_query="$q"
local eq='Test Query with Hotstrings removed'
local tc='**'
local eh='aabc b c'
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
filtered_query=''
local t_name='Trigger chars before & after hotstring'
local q='aabc** Test **B$! Query with Hotstrings removed **c123'
raw_query="$q"
local eq='Test Query with Hotstrings removed'
local tc='**'
local eh='aabc B$1! c123'
hotstring_scan_test "$t_name" "$q" "$tc" "$eh" "$eq"
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 "Execution time in nano seconds: $execution_time"
}
run_all_tests(){
set -x
hotstring_scan_tests
}
run_all_tests
# performance_test
【问题讨论】:
-
这有帮助吗(来自 bash 手册):如果模式存储在 shell 变量中,引用变量扩展会强制将整个模式作为字符串匹配?
标签: regex bash regex-group