正则表达式使用总结(包括非捕获匹配)

本文详细解析了正则表达式的构成元素,包括常用字符及其含义、字符个数限定符等,并介绍了如何利用非获取匹配实现精准匹配需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式主要分为两部分

1.字符:(都是单个字符)

  1.   .  : 表示任意单个字符
  2. \w :表示字母或数字:a-zA-Z0-9, \W则与\w相反, 这样一正一反下来,就表示所有的字符,完全的,一字不漏的。
  3. \s : 表示空白字符,包括空格,制表符,回车, \S表示与\s相反。
  4. \d : 表示数字0-9, \D 表示与\d相反。
  5. [] :  要做更精确地匹配,可以用[]表示范围, [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;取反,^还能做为取反使用,例如[^abc]表示不包含a,b和c
  6. | : A|B可以匹配AB,所以(J|j)ava(S|s)cript可以匹配'JavaScript''Javascript''javaScript'或者'javascript'。注意, (J|j)ava(S|s)cript 是加了分组功能的, 什么是分组? 除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。
  7. :表示行的开头,^\d表示必须以数字开头,^还能做为取反使用,例如[^abc]表示不包含a,b和c。
  8. :表示行的结束,\d$表示必须以数字结束。
  9. 特例:如何表示一个特定的字符串?用小括号括起来,(abc)

字符就介绍到这里,基本够用了。

2.字符个数(限定符):

上面介绍了正则表达式常用的字符,但是一个完整的正则表达式必须要包含字符+字符个数,下面介绍常用的表达字符个数的方式:

  1. ? : 表示0个或1个字符, 例如"\w?" 表示0个或者1个 字母或数字。除了表示个数,?还可以用于阻止贪婪匹配,可以在正则表达式后面加个?,例如\d+贪婪匹配文章中所有数字,\d+?就可以让\d+采用非贪婪匹配,只匹配第一个数字???
  2. * : 表示任意个字符(包括0个)。
  3. +: 表示至少一个字符。
  4. {n}:表示n个字符。
  5. {n,m}:表示n到m个字符。

Note: 怎样指定某个字符串的个数?用小括号括起来,(abc)*,可以匹配abc,abcabc........

3.总结:

正则表达式其实就是字符+字符个数,掌握这个窍门,只要不是特别复杂的情况下,基本是够用了。

4.非捕获匹配:

有时候会有些变态点儿的需求-- 匹配结果中pattern(正则表达式)部分不出现,这时候就需要非捕获匹配了,匹配的结果中没有pattern部分的内容

4.1案例

我们来看一下这种情况:第三项中(用户名)含有敏感信息,请将其替换为 "xxxxxx"

"success","1","admin","2020-11-10T01:20:30"

"success","2","testuser","2020-11-10T01:21:30"

怎么找到第三项呢? 使用非捕获匹配,也就是说将前三项都写到正则表达式中,但是前两项写为非捕获匹配,最终就能只匹配到第三项

这里给出一个答案:反向肯定预查  (?<=(\"\w*\",\"\w*\",))\"\w*\"

上面案例的代码如下:

没有使用上面的正则表达式(?<=(\"\w*\",\"\w*\",))\"\w*\",而是用{0,10}代替了*,因为:在后行正则表达式中,Java正则引擎不允许没有明确最大长度匹配的可变长度文本。这意味着我们不能在后行模式中使用 * 或 + 限定符。

但在后行正则中,Java正则引擎允许有限制或明确长度的重复行为。通过在后行表达式中使用有限的限定符,这样就能在Java正则表达式中给我们替代的解决方案。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NoFetchMatchTest {
    public static void main(String[] args) {
        String content = "\"success\",\"ss\",\"admin\",\"2020-11-10T01:20:30\"";
        String regStr  = "(?<=\"\\w{0,10}\",\"\\w{0,10}\",)\"\\w*\"";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group()); // "admin"
        }
    }
}

4.2非捕获匹配详细

下面给出几个常用的非捕获匹配:

 Note:能够全部匹配,并且只返回自己需要的那部分字符串

正向:从左往右,正则表达式在右侧

反向:从右向左, 正则表达式在左侧

(?=pattern)

非捕获匹配 -> 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要捕获供以后使用。

举例说明,“Linux(?=3.0|3.1|3.2|3.3)”能匹配“Linux3.1”中的“Linux”,但不能匹配“Linux4.0”中的“Linux”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

非捕获匹配 -> 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配同样不需要捕获供以后使用。

举例说明,“Linux(?!3.0|3.1|3.2|3.3)”能匹配“Linux4.0”中的“Linux”,但不能匹配“Linux3.0”中的“Linux”。与正向肯定预查(?=pattern)正好相反

(?<=pattern)

非捕获匹配 -> 反向肯定预查,与正向肯定预查类似,只是方向相反,即放置位置相反,一个在前(反向),一个在后(正向)。

举例说明,“(?<=xp|7|10)Windows”能匹配“10Windows”中的“Windows”,但不能匹配“98Windows”中的“Windows”。

(?<!pattern)非捕获匹配 -> 反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!xp|7|10)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“10Windows”中的“Windows”。

(?:pattern) 

捕获匹配(匹配全部字符),匹配包括pattern部分的全部字符,不进行存储(不进行分组,上面几个都会存储分组)供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。

举例说明,“industr(?:y|ies)”能够匹配"industries"中的"industr"。“industr(?:y|ies)”是一个比“industry|industries”更简略的表达式。

当然可以配合使用, 下面的例子中将网址www.google.com匹配出来 

<a target=_blank href="www.google.com">谷歌浏览器</a>

 正则表达式:(?<=(href=")).{1,100}(?=(">)), 同时使用了反向肯定预查和正向肯定预查。注意,这里是做了分组的。

5.正则表达式验证网站:

可以在这个网址: 在线正则表达式测试, 去验证自己所写的正则表达式。

在这个网址中,即可以验证自己的正则表达式,又可以测试匹配后的替换功能。例如下面的例子中可以匹配用户名,并且将用户名替换为"xxxxxx"。

React Hooks 是 React 16.8 中新增的特性,它可以让你在函数组件中使用 state、生命周期钩子等 React 特性。使用 Hooks 可以让你写出更简洁、可复用且易于测试的代码。 React Hooks 提供了一系列的 Hook 函数,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useImperativeHandle、useLayoutEffect 和 useDebugValue。每个 Hook 都有特定的用途,可以帮助你处理不同的问题。 下面是 React Hooks 的一些常用 Hook 函数: 1. useState useState 是最常用的 Hook 之一,它可以让你在函数组件中使用 state。useState 接受一个初始状态值,并返回一个数组,数组的第一个值是当前 state 值,第二个值是更新 state 值的函数。 ``` const [count, setCount] = useState(0); ``` 2. useEffect useEffect 可以让你在组件渲染后执行一些副作用操作,比如订阅事件、异步请求数据等。useEffect 接受两个参数,第一个参数是一个回调函数,第二个参数是一个数组,用于控制 useEffect 的执行时机。 ``` useEffect(() => { // 这里可以执行副作用操作 }, [dependencies]); ``` 3. useContext useContext 可以让你在组件树中获取 context 的值。它接受一个 context 对象,并返回该 context 的当前值。 ``` const value = useContext(MyContext); ``` 4. useRef useRef 可以让你在组件之间共享一个可变的引用。它返回一个对象,该对象的 current 属性可以存储任何值,并在组件的生命周期中保持不变。 ``` const ref = useRef(initialValue); ref.current = value; ``` 5. useCallback useCallback 可以让你缓存一个函数,以避免在每次渲染时都创建一个新的函数实例。它接受一个回调函数和一个依赖数组,并返回一个 memoized 的回调函数。 ``` const memoizedCallback = useCallback(() => { // 这里是回调函数的逻辑 }, [dependencies]); ``` 6. useMemo useMemo 可以让你缓存一个计算结果,以避免在每次渲染时都重新计算。它接受一个计算函数和一个依赖数组,并返回一个 memoized 的计算结果。 ``` const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` 以上就是 React Hooks 的一些常用 Hook 函数,它们可以帮助你更好地处理组件状态、副作用、上下文和性能优化等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值