编程题--正则表达式

本文深入解析了正则表达式匹配算法,特别是如何处理'.'和'*'这两个特殊字符,通过递归方法实现了字符串与模式的匹配。文章详细解释了在不同情况下,如模式匹配字符的下一个字符是'*'或正常字符时的处理策略。
部署运行你感兴趣的模型镜像

题目描述

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。

分析:

首先,考虑特殊请况

  1. 两个字符串都为空,返回true.
  2. 当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法匹配成功了,而如果第一个字符串空了,第二个字符串非空,还可能匹配成功的。Eg: a*a*a*a*)

正常情况:每次分别在str和pattern中取一个字符进行比较,如果匹配,则匹配下一个字符,否则,返回不匹配。

分析:递归实现

   设匹配递归函数 match(str, pattern)。

1.  如果模式匹配字符的下一个字符是‘*’:

如果pttern当前字符和str的当前字符匹配,:有以下三种可能情况

  •     pttern当前字符能匹配 str 中的 0 个字符:match(str, pattern+2)
  •     pttern当前字符能匹配 str 中的 1 个字符:match(str+1, pattern+2)
  •     pttern当前字符能匹配 str 中的 多 个字符:match(str+1, pattern)

 如果pttern当前字符和和str的当前字符不匹配:

  •   pttern当前字符能匹配 str 中的 0 个字符:(str, pattern+2)

2.  如果模式匹配字符的下一个字符不是‘.’:

  对于 ‘.’ 的情况比较简单,’.’ 和一个字符匹配 match(str+1, pattern+1)

3. 如果模式匹配字符的下一个字符是正常字符,且 *str == *pattern,

    递归下一个字符 :match(str+1, pattern+1)

 

实现

注:上边这几类情况,再代码实现中,可以进行归类合并,详见下面的代码:

//正则表达式的匹配
	//注:空字符串和“.*”是匹配的
	bool match(char* str, char* pattern)
    {
        //特殊情况处理
		//如果str和pattern都为NULL, 返回true
        if(*str == '\0' && *pattern == '\0')
		{
			return true;
		}
		//str不为NULL, pattern为NULL,一定不匹配,返回false.
		//注:str为NULL, pattern不为NULL时,可能匹配。 eg: a*a*a*a*
		if(*str != '\0' && *pattern == '\0')
		{
			return false;
		}

		//递归进行处理(正常情况)
		if(*(pattern+1) == '*') //pattern可匹配0次,1次或多次
		{
			if(*pattern == *str || (*str != '\0' && *pattern == '.'))
			{
				return match(str,pattern+2) //*pattern == *str请况下,匹配0个
					|| match(str+1,pattern); //匹配多个
			}
			else //*pattern != *str请况下匹配0次,pattern+2
			{
				return match(str,pattern+2);
			}
		}

        //pattern下一个字符为. 或正常字符即(*str == *pattern)
		if((*str != '\0' && *pattern == '.') || (*str == *pattern))
		{
			return match(str+1, pattern+1);
		}

		return false;
    }

总结

      在写这道题时,首先理解什么是正则表达式,对“*”和“.”的匹配模式进行理解,然后对各种情况进行分析,归类。再具体写代码实现。

图解

 

 

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>我们要求匹配00到99之间的数字,包括00, 01, ..., 99。注意,这里允许前导零,因为00也是允许的。 所以,我们需要匹配两位数字,第一位可以是0到9,第二位也可以是0到9。 但是,如果我们直接写`[0-9][0-9]`,那么它会匹配任意两位数字,包括00到99,这正好满足要求。 然而,我们需要注意:这个正则表达式会匹配字符串中的任意两位数字,所以我们需要确保匹配的是整个字符串(即只有这两个数字),而不是一个更长字符串的一部分。 因此,我们应该使用`^`和`$`来限定字符串的开头和结尾,以确保整个字符串就是这两个数字。 所以正则表达式为:`/^[0-9][0-9]$/` 但是,我们也可以使用`/^\d{2}$/`,因为`\d`等价于`[0-9]`,而`{2}`表示前面的字符恰好出现2次。 但是,注意:如果是在某些编程语言中(比如Java),我们可能需要转义反斜杠,所以写成字符串形式可能是`"^\\d{2}$"`(双反斜杠,因为字符串中反斜杠需要转义)。 另外,如果使用`[0-9]`,则正则表达式为`"^[0-9]{2}$"`。 所以,我们有两种写法: 1. `^[0-9]{2}$` 2. `^\d{2}$` 这两种写法都可以匹配00到99之间的所有两位数字。 但是,请注意,这个正则表达式也会匹配00, 01, 02, ..., 09,这些在数值上表示0到9,但是作为字符串是两位的。根据需求,我们就是要匹配00到99,所以这是符合的。 测试用例: "00" -> 匹配 "01" -> 匹配 "99" -> 匹配 "0" -> 不匹配(只有一位) "100"-> 不匹配(三位) "a0" -> 不匹配(包含非数字) 在代码中使用(以JavaScript为例): function isValidTwoDigitString(str) { return /^[0-9]{2}$/.test(str); } 或者: function isValidTwoDigitString(str) { return /^\d{2}$/.test(str); } 在HTML表单中,可以使用pattern属性: <input pattern="[0-9]{2}" title="请输入00-99之间的两位数字"> 注意:在HTML的pattern属性中,我们通常不需要写^和$,因为HTML5的pattern属性默认就是全匹配。但是为了确保安全,最好测试一下浏览器的行为。根据规范,pattern属性是隐式添加了^和$的,所以只写`[0-9]{2}`就表示整个输入必须是两位数字。 但是,根据引用[2]中的内容,我们需要注意匹配的优先级问题。不过在这个正则表达式中,我们没有使用选择符(|),所以不会出现优先级问题。 另外,引用[1]中提到了匹配1-99的数字,使用的是`[1-9][0-9]?`,这和我们这里的需求不同(我们包括00-09,并且要求必须是两位)。 因此,针对00到99的正则表达式为:`^\d{2}$` 或 `^[0-9]{2}$` 下面我们给出在几种编程语言中的使用示例: 1. JavaScript: let regex = /^\d{2}$/; console.log(regex.test("00")); // true console.log(regex.test("42")); // true console.log(regex.test("9")); // false 2. Java (注意转义): import java.util.regex.Pattern; import java.util.regex.Matcher; public class Main { public static void main(String[] args) { Pattern pattern = Pattern.compile("^\\d{2}$"); System.out.println(pattern.matcher("00").matches()); // true System.out.println(pattern.matcher("99").matches()); // true System.out.println(pattern.matcher("100").matches()); // false } } 3. Python: import re pattern = re.compile(r'^\d{2}$') print(pattern.match("00") is not None) # True print(pattern.match("09") is not None) # True print(pattern.match("123") is not None) # False 4. HTML: <input type="text" pattern="[0-9]{2}" title="两位数字(00-99)"> 注意:在HTML中,如果输入为空,则pattern不会被验证(除非有required属性)。所以如果允许空,那么不要加required;如果不允许空,可以加上required。 另外,如果需求是输入00到99(包括00和99)的整数,那么用这个正则表达式即可。 但是,如果需求是输入00到99的整数,但是不允许00呢?那么我们需要修改正则表达式。不过根据问题,我们要求的是00到99,所以00是允许的。 总结:正则表达式为`^\d{2}$`或`^[0-9]{2}$`。 相关问题: 1. 如何用正则表达式匹配00到99,但不包括00? 2. 正则表达式如何匹配0到100之间的整数(包括0和100)? 3. 如何用正则表达式匹配01到99(即不允许00,但允许01到99)? 4. 正则表达式`\d`和`[0-9]`有什么区别?在什么情况下它们不等价?</think>要匹配 **00 到 99 之间的两位数字**(包括前导零),可以使用正则表达式: `/^[0-9]{2}$/` 或等效写法 `/^\d{2}$/` ### 正则表达式解析: 1. **`^`**:匹配字符串**开头** 2. **`[0-9]`** 或 **`\d`**:匹配任意数字(0-9) 3. **`{2}`**:精确匹配前一个字符/字符组 **2 次** 4. **`$`**:匹配字符串**结尾** ### 关键特性: - **严格长度控制**:确保输入必须是 **2 位字符** - **数值范围**:覆盖 00, 01, 02, ..., 99 的所有组合 - **允许前导零**:`00` 和 `01` 被视为合法输入(区别于正整数匹配) ### 验证示例: | 输入 | 是否匹配 | 说明 | |--------|----------|--------------------| | `"00"` | ✅ | 最小数字(00) | | `"99"` | ✅ | 最大数字(99) | | `"05"` | ✅ | 包含前导零 | | `"5"` | ❌ | 位数不足 | | `"100"`| ❌ | 位数超出 | | `"1a"` | ❌ | 包含非数字字符 | --- ### 代码实现示例: ```javascript // JavaScript function isValidTwoDigit(str) { return /^[0-9]{2}$/.test(str); } console.log(isValidTwoDigit("00")); // true console.log(isValidTwoDigit("42")); // true console.log(isValidTwoDigit("9")); // false ``` ```java // Java import java.util.regex.*; public class Main { public static void main(String[] args) { Pattern pattern = Pattern.compile("^[0-9]{2}$"); System.out.println(pattern.matcher("05").matches()); // true System.out.println(pattern.matcher("123").matches()); // false } } ``` ```python # Python import re pattern = re.compile(r'^[0-9]{2}$') print(bool(pattern.match("99"))) # True print(bool(pattern.match("7"))) # False ``` ### HTML 表单应用: ```html <input type="text" pattern="[0-9]{2}" title="请输入00-99之间的两位数字(如05, 42)" > ``` --- ### 与正整数匹配的差异: | 需求 | 正则表达式 | 是否允许 `00` | 是否允许 `05` | |--------------------|------------------|---------------|---------------| | **00-99**(本题) | `^[0-9]{2}$` | ✅ | ✅ | | **10-99**(正整数)| `^[1-9][0-9]$` | ❌ | ❌(因 `05` 被视为 5)[^1] | --- ### 相关问题: 1. 如何用正则表达式匹配 **00 到 99 但不包括 00**? → 解:`/^(0[1-9]|[1-9][0-9])$/`(允许 `01`-`99`) 2. 正则表达式如何匹配 **0 到 100 的整数**(包括 0 和 100)? → 解:`/^([0-9]|[1-9][0-9]|100)$/` [^2] 3. 在 Java 中,`matches()` 和 `find()` 方法有何区别? → `matches()` 要求整个字符串完全匹配,`find()` 搜索子串匹配[^2] 4. `[0-9]` 和 `\d` 是否完全等价? → 在大多数场景等价,但 `\d` 可能匹配非阿拉伯数字(如全角数字),取决于正则引擎配置 [^1]: 匹配1-99的正则方案 [^2]: Java匹配方法与优先级处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值