Day 30 通配符匹配

通配符匹配

给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。

示例 1:

输入:

s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。

示例 3:

输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'

示例 4:

输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".

示例 5:

输入:
s = "acdcb"
p = "a*c?b"
输入: false

使用语言:Java
双指针贪心算法

class Solution {
  public boolean isMatch(String s, String p) {
    if (p==null||p.isEmpty())return s==null||s.isEmpty();
    int i=0,j=0,istart=-1,jstart=-1,slen=s.length(),plen=p.length();
    while (i<slen){
       
        if (j<plen&&(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')){
            i++;
            j++;
        }else if (j<plen&&p.charAt(j)=='*'){
            istart=i;
            jstart=j++;
        }else if (istart>-1){
            i=++istart;
            j=jstart+1;
        }else {
            return false;
        }
    }
    while (j<plen&&p.charAt(j)=='*')j++;
    return j==plen;
}
}

在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/wildcard-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

<think>好的,用户现在想了解Tcl中的文字匹配。之前他们问过关于sed只打印一次的问题,现在转向Tcl,可能是需要在脚本中进行字符串处理。首先,我需要确认用户的需求,他们可能是在写Tcl脚本时需要匹配特定模式的字符串,或者处理文本数据。 用户可能对Tcl的基本字符串操作不太熟悉,或者想了解更高级的模式匹配方法,比如正则表达式。需要分步骤解释,从简单到复杂。首先介绍基本的字符串命令,比如string match,然后逐步引入正则表达式的使用,包括regexp和regsub。 考虑到用户之前使用过sed,可能对正则表达式有一定了解,但Tcl的正则语法可能有所不同,需要指出差异。比如Tcl使用{}而不是//来界定模式,并且默认是贪婪匹配。同时,需要注意Tcl中的转义字符,比如使用\来转义特殊字符,或者用{}避免转义。 另外,用户可能需要知道匹配后的处理,比如提取子匹配项,替换文本,或者控制匹配的行为(如大小写敏感)。因此,需要给出具体的例子,说明如何捕获变量,进行替换操作,以及使用选项如-nocase。 还需要提醒用户常见的陷阱,比如特殊字符的转义,匹配模式与string match和正则表达式的区别,以及贪婪匹配的问题。这些都是在实际使用中容易出错的地方,提前说明可以帮助用户避免错误。 最后,总结不同方法的适用场景,帮助用户根据需求选择合适的方法。比如简单通配符匹配用string match,复杂模式用正则表达式。同时,提供性能优化的建议,比如预编译正则表达式,处理大文本时的注意事项。 现在需要组织这些内容,确保结构清晰,步骤明确,示例易懂,符合用户之前接受的回答风格。使用代码块展示命令,用注释说明关键点,注意事项部分突出常见问题,对比不同方法的优缺点,帮助用户做出正确选择。</think>在 Tcl 脚本语言中,字符串匹配主要通过 `string match` 命令和正则表达式实现。以下是分步详解及典型用法: --- ### 一、基础通配符匹配 (`string match`) **语法**: ```tcl string match pattern string ``` **特点**: - 支持 `*`(匹配任意字符)和 `?`(匹配单个字符) - 默认区分大小写 - 不直接支持正则表达式 **示例**: ```tcl # 匹配以 ".txt" 结尾的文件名 set filename "report.txt" if {[string match *.txt $filename]} { puts "是文本文件" } # 匹配3位数字编号 set id "A123" if {[string match ??? $id]} { puts "长度3位" } else { puts "长度不足" } ``` 输出: ``` 是文本文件 长度不足 ``` --- ### 二、正则表达式匹配 (`regexp`) **语法**: ```tcl regexp ?options? pattern string ?matchVar? ?subVar1 ...? ``` **核心功能**: - 支持 Perl 风格正则表达式 - 可捕获子匹配项 - 支持模式修饰符 (如 `-nocase` 忽略大小写) **典型场景**: ```tcl # 提取邮箱地址 set text "联系 admin@example.com 或 support@test.org" if {[regexp {([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})} $text match email]} { puts "找到邮箱:$email" } # 多子匹配项捕获 set date "2024-07-20" regexp {(\d{4})-(\d{2})-(\d{2})} $date full year month day puts "年份:$year, 月份:$month, 日期:$day" ``` 输出: ``` 找到邮箱:admin@example.com 年份:2024, 月份:07, 日期:20 ``` --- ### 三、正则替换 (`regsub`) **语法**: ```tcl regsub ?options? pattern string replacement newStringVar ``` **实用示例**: ```tcl # 隐藏手机号中间四位 set phone "13812345678" regsub {(\d{3})\d{4}(\d{4})} $phone {\1****\2} masked puts "脱敏号码:$masked" ;# 输出 138****5678 # 多行模式处理 set html "<p>First line\n<h1>Title</h1>\n</p>" regsub -all -nocase {(</?h1>)} $html "" cleaned puts $cleaned ;# 移除所有<h1>标签 ``` --- ### 四、高级技巧 1. **模式修饰符**: ```tcl regexp -nocase {^error} $str ;# 忽略大小写匹配 regexp -line {^start} $text ;# 多行模式下匹配行首 ``` 2. **预编译正则表达式**: ```tcl set re [regexp -expanded { ^\d+ # 数字开头 \s+ # 至少一个空格 [A-Za-z]+ # 跟随字母 }] regexp $re $input ``` 3. **非贪婪匹配**: ```tcl regexp {<.*?>} "<a>link</a>" ;# 匹配最短的标签 <a> ``` --- ### 五、常见问题与解决方案 | 问题类型 | 错误示例 | 修正方案 | |---------|---------|---------| | **特殊字符未转义** | `regexp {file.txt} $str` | 改为 `regexp {file\.txt} $str` | | **误用 string match 逻辑** | `string match *active* $str` | 改为 `regexp {active} $str` | | **贪婪匹配错误** | `regexp {<.*>} "<a><b>"` 匹配整个字符串 | 使用 `<.*?>` 实现非贪婪匹配 | --- ### 六、性能优化建议 1. 对高频使用的正则表达式使用 `regexp -about` 预编译检查 2. 避免在循环中重复编译正则表达式 3. 处理大文本时优先使用 `regsub -all` 而非多次替换 --- 通过合理选择 `string match`(简单通配符)或 `regexp`(复杂模式),可高效完成从文件名过滤到数据提取的各种文本处理任务。实际开发中建议:先用 `string match` 快速筛选,需要精细匹配时再使用正则表达式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值