ue中使用正则表达式来替换-正则表达式-的捕获组与非捕获组

本文介绍如何利用正则表达式中的分组概念来精确地匹配和提取文本中的特定内容,包括普通捕获组、命名捕获组及非捕获组的应用场景,并通过实例演示如何在实际开发中运用这些技巧。

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

在ue中,经常遇到需要去掉字符串中的空格。比如,在列模式下编辑得到的内容往往含有很多不需要的空格,这个时候需要使用正则表达式来替换。

  这里使用的是ue中的unix正则表达式引擎,替换表达式是:"(/s*)([a-z]+)/s*" 替换为:"/2"。

解释: 上面的正则表达式是将“ ”内的首尾含有的空格去掉,保留中间的小写字母。 这里涉及到分组的概念。

当需要在正则表达式的后面引用前面已经匹配的内容或者在被替换为这部分需要引用正则表达式中已经匹配的内容的时候,就需要使用到分组。

  捕获组是可以被捕获的分组,其中显式命名的捕获组称为命名捕获组。

 

见:

 

正则表达式分组相关的知识

一、组的分类
正则中的组有捕获组和非捕获组,而捕获组又分为普通的捕获组和命名捕获组,分别为
捕获组:(exp)
命名捕获组:(? <name> exp)
非捕获组:(?:exp)

二、组的作用
1、捕获组的作用

捕获组的作用是将正则表达式exp匹配到的内容保存到组里,供以后使用

比如这样一个字符串:
<a href="http://bbs.youkuaiyun.com" title="床上等你"> 优快云 </a>
我想得到网址,而它符合的规则是在 <a...> 标签内,那就可以这样做

C# code
string test = "<a href=/"http://bbs.youkuaiyun.com/" title=/"床上等你/">优快云</a>"; Match m = Regex.Match(test, @"<a/s*href=""([^""]*)""[^>]*>", RegexOptions.IgnoreCase); if (m.Success) MessageBox.Show(m.Groups[1].Value);


上面的正则表达式匹配到了 <a href="http://bbs.youkuaiyun.com" title="床上等你"> ,而我们想得到网址,表达式其它部分只是为了保证取到的网址是在 <a...> 标签内的,所以这里用到的捕获组,把匹配到的网址保存到捕获组里,然后用m.Groups[1].Value得到这个捕获组所匹配到的内容
m.Groups[1].Value是一种对捕获的引用方式,还有另外一种引用方式m.Result("$1"),效果是一样的

普通捕获组是用1,2,3...这样的自然数对捕获组进行引用的
而命名捕获组可以不用去数捕获组的序号,直接通过捕获组的命称对它进行引用

C# code
string test = "<a href=/"http://bbs.youkuaiyun.com/" title=/"床上等你/">优快云</a>"; Match m = Regex.Match(test, @"<a/s*href=""(?<url>[^""]*)""[^>]*>", RegexOptions.IgnoreCase); if (m.Success) MessageBox.Show(m.Groups["url"].Value);



至于捕获组的分组命名及序号排序规则,在后面说明

2、非捕获组的作用
非捕获组的作用有两个,第一个比较常用,第二个了解一下即可

(1)、节省系统资源,提高效率
在使用“ ¦”表示“或”的关系时,稍微复杂的情况,需要用()来限制“ ¦”的作用范围,否则即表示“ ¦”的左右两侧整体为“或”的关系,这是题外话,这里不详细说明了,还有用{num}来表达式匹配次数时,有时前面也要用到()限制作用范围
而使用()来限制作用范围的同时,默认情况下会把匹配到的结果保存到一个捕获组里,而大多数时候,我们是不需要保存这部分内容的,这就带来一定的副作用,浪费了系统资源,降低了效率
非捕获组的一个作用就是用来消除这种副作用的,(?:exp)用来匹配exp所表示的规则,但不将匹配结果保存到捕获组里

比如匹配HH:mm:ss这样的时间

C# code
MessageBox.Show(Regex.IsMatch("18:23:55", "^(?:[01][0-9]|2[0-3])(?::[0-5][0-9]){2}$").ToString());


(?:[01][0-9] ¦2[0-3])验证小时部分是否符合规则,但不会将匹配结果保存到捕获组里
(?::[0-5][0-9]){2}验证了分秒部分,但不会将匹配结果保存到捕获组里

(2)、在使用Regex.Split方法时,起到与RegexOptions .ExplicitCapture参数相同的作用,这个用得不多,了解一下就行了

三、捕获组分组命名及序号排序
普通捕获组是按“(”从左到右出现的先后顺序以自然数1,2,3...进行命名的
命名捕获组就是以(? <name> exp)中的name进行命名的

但是要注意一点,在表达式匹配成功的前提下,$0在任何情况下都表示整个表达式所匹配到的内容,m.Groups[0].Value表示整个表达式匹配到的内容,可以简写为m.Value

另外就是命名捕获组除了可以用name对它进行引用外,还可以通过序号对它引用,它的命名规则为:先对普通捕获组从左到右进行序号命名,然后再从开头,从左到右对命名捕获组进行序号命名,举例如下

<a/s*href="(? <url> [^"]*)"/s*title="([^"]*)"[^> ]*> (? <text> [/s/S]*?) </a>
2 url 1 3 text

C# code
string test = "<a href=/"http://bbs.youkuaiyun.com/" title=/"床上等你/">优快云</a>"; Match m = Regex.Match(test, @"<a/s*href=""(?<url>[^""]*)""/s*title=""([^""]*)""[^>]*>(?<text>[/s/S]*?)</a>", RegexOptions.IgnoreCase); if (m.Success) { richTextBox1.Text += m.Groups[0].Value + "/n"; //<a href="http://bbs.youkuaiyun.com" title="床上等你">优快云</a> richTextBox1.Text += m.Groups[1].Value + "/n"; //床上等你 richTextBox1.Text += m.Groups[2].Value + "/n"; //http://bbs.youkuaiyun.com richTextBox1.Text += m.Groups["url"].Value + "/n"; //http://bbs.youkuaiyun.com richTextBox1.Text += m.Groups[3].Value + "/n"; //优快云 richTextBox1.Text += m.Groups["text"].Value + "/n"; //优快云 }



四、组的另一种引用方式
除了上面 m.Groups[1].Value 和 m.Result("$1") 这两种对结果集进行处理时的引用方式外,还有在替换时的一种引用方式,举例如下

只保留网址和链接文字,去掉 <a...> 标签中其它无用信息

C# code
string test = "<a href=/"http://bbs.youkuaiyun.com/" title=/"床上等你/">优快云</a>"; string result = Regex.Replace(test, @"<a/s*href=""([^""]*)""/s*title=""([^""]*)""[^>]*>(?<text>[/s/S]*?)</a>", @"<a href=""$1"">${text}</a>", RegexOptions.IgnoreCase); MessageBox.Show(result);



普通捕获组就是用$number来引用,而命名捕获是用${name}来引用 

<think>嗯,用户想要从字符串"tokenCheck-43fd64jhr86gdfgd459uea4rt56yu7uy"中提取"tokenCheck-"后面的部分。首先,我需要确定如何用Java实现这个操作。可能的办法有几种,比如使用substring方法,或者用split分割字符串,或者正则表达式匹配。 首先,substring方法应该是最直接的。找到"tokenCheck-"的位置,然后截取后面的部分。用户给出的字符串中,前缀是固定的"tokenCheck-",所以可以用indexOf找到这个子字符串的位置,然后加上前缀的长度,得到起始索引,再用substring截取。 然后,用split的话,可以用"-"作为分隔符,分割成数组,然后取第二个元素。不过如果字符串中有多个"-",可能会分割成多个部分,这时候可能需要考虑具体情况,但在这个例子中,应该没问题。 正则表达式的话,可以用Pattern和Matcher来匹配"tokenCheck-(.*)",然后获取捕获组的内容。这种方法更灵活,尤其是当格式更复杂的时候。 需要考虑异常情况,比如如果字符串中没有"tokenCheck-"前缀怎么办?这时候indexOf会返回-1,substring会抛出异常,所以在实际应用中可能需要先检查是否存在该前缀,或者用try-catch处理异常。 用户给的例子中确实包含该前缀,所以直接使用substring是可行的。不过代码中最好还是加入检查,避免运行时错误。例如,先检查index是否不等于-1,再进行截取。 另外,split方法在分隔符出现在后面时可能会有问题,比如如果有多个分隔符,比如"tokenCheck-abc-def",split("-")会得到["tokenCheck", "abc", "def"],所以取索引1的话只能得到"abc"。但用户的需求是截取整个后面的部分,所以split方法在这种情况下可能不适用,除非分隔符只出现一次。所以在这种情况下,使用substring更可靠。 综上,最合适的方法是使用substring,先找到前缀的位置,加上长度,然后截取。另外需要处理不存在前缀的情况,返回空字符串或者抛出异常,根据需求决定。 所以,给出代码示例,包含两种方法:substring和split,并说明它们的优缺点。同时提醒异常处理,比如检查index是否有效。</think>要截取字符串"tokenCheck-43fd64jhr86gdfgd459uea4rt56yu7uy"中"tokenCheck-"后面的内容,可以使用以下两种方法实现: ```java // 方法1:使用substring和indexOf String original = "tokenCheck-43fd64jhr86gdfgd459uea4rt56yu7uy"; int prefixIndex = original.indexOf("tokenCheck-"); if (prefixIndex != -1) { String result = original.substring(prefixIndex + "tokenCheck-".length()); System.out.println(result); // 输出:43fd64jhr86gdfgd459uea4rt56yu7uy } // 方法2:使用split分割 String[] parts = original.split("tokenCheck-"); if (parts.length > 1) { System.out.println(parts[1]); // 输出相同结果 } ``` **解释说明**: 1. `indexOf()`方法用于定位子字符串的位置,找到"tokenCheck-"的起始索引 2. `substring()`方法从该位置加上前缀长度开始截取 3. `split()`方法通过分割字符串获取后半部分 4. 两个方法都包含有效性检查,避免出现`StringIndexOutOfBoundsException` **注意事项**: - 当原始字符串不包含前缀时,indexOf会返回-1 - split方法在分隔符多次出现时可能返回多个分段 - 推荐优先使用substring方法,性能更好且逻辑更直观
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

walkingmanc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值