RegEx用于匹配包含短语A和C但不包含短语B

时间:2019-05-06 23:03:50

标签: regex grep

我想要一个正则表达式,当“ 1234”在“ cat”之前,而“ he”不在时,找到“ cat”的所有匹配项。例如,在下面的文本框中,前2个组包含匹配项,而第3个组则不包含匹配项:

1234
cat
bat5

1234
extra
catbat5

1234
he
catbat5

对跨多行grep的解决方案有何想法? -P Perl操作无效。

编辑: 我意识到grep不支持环顾四周操作,因此我删除了我提供的不再适用的中途解决方案。

编辑2: 看来grep BRE或ERE无法解决此问题。如果将来还有其他人有这个问题,您将想尝试其他方法。您可以按照Ed Morton的建议尝试awk。您也可以创建最终对我有用的功能(请参见下面的答案)。

2 个答案:

答案 0 :(得分:1)

最终对我有用的是创建一个函数:

#!/bin/ksh
# Search a file line by line for Phrase A followed by Phrase C,
# without Phrase B existing between them.
# Param 1 - Phrase A
# Param 2 - Phrase B
# Param 3 - Phrase C
# Param 4 - File to search
find_target_output(){
    A=$1
    B=$2
    C=$3
    found_A=0
    found_C=0

    file="$4"
    while IFS= read line
    do
        # First, look for A
        if [ $found_A -eq 0 ]; then
            test "${line#*$A}" != "$line" && found_A=1 && echo "Found A"
        # Then, look for C. Stop reading once it's found.
        # If B is found before C, break immediately to return failure
        elif [ $found_C -eq 0 ]; then
            test "${line#*$B}" != "$line" && echo "Found B" && break
            test "${line#*$C}" != "$line" && found_C=1 && echo "Found C" && break
        fi
    done <"$file"

    if [ $found_C -eq 0 ]; then
        echo "FAIL::$file"
    else
        echo "PASS::$file"
    fi
    return $found_C
}

答案 1 :(得分:0)

只需使用正确的工具即可完成工作。在任何UNIX盒子上的任何外壳中都有任何awk:

tweets_df['label'] = tweets_df['tidy_tweet'].transform(sentiment_value)

以上内容基于您想要$ awk -v RS= -v ORS='\n\n' '/1234.*cat/ && !/he.*cat/' file 1234 cat bat5 1234 extra catbat5 的问题中语句的字面解释。如果那是错误的,那么请更新您的问题以澄清并提供更全面的示例输入/输出,以真正满足您的所有要求。例如,使用GNU awk将第三个arg匹配到((all matches for "cat" when "1234" precedes it and "he" does not.不得介于1234和cat之间):

he

或另一个(该块必须只包含1234和cat,但不能包含他:

$ awk -v RS= -v ORS='\n\n' 'match($0,/1234.*cat/,a) && a[0] !~ /he/' file
1234
cat
bat5

1234
extra
catbat5

或者您可能只想打印$ awk -v RS= -v ORS='\n\n' '/1234/ && /cat/ && !/he/' file 1234 cat bat5 1234 extra catbat5 块,而连续文本块之间没有1234...cat

he

满足您的需求的可能性如此之多...