52、.NET 正则表达式的使用与特性

.NET 正则表达式的使用与特性

1. 正则替换与特殊序列

在 .NET 中,正则表达式的替换功能十分强大。例如,它可以将 some random spacing 这样的字符串进行处理。在搜索和替换时,会使用 LeadingWS 匹配的长度作为偏移量(即跳过的字符数)。这里利用了 Match 对象的一个便利特性,即使匹配失败,其 Length 属性仍可使用,失败时 Length 属性值为 0,这恰好满足对整个目标应用 AnyWS 的需求。

1.1 特殊替换序列

Regex.Replace 方法和 Match.Result 方法都接受一个特殊解释的“替换”字符串。其中的特殊序列会被匹配中的相应文本替换,具体如下表所示:
| 序列 | 替换内容 |
| ---- | ---- |
| $& | 正则表达式匹配的文本(也可表示为 $0 ) |
| $1 , $2 , … | 相应捕获括号组匹配的文本 |
| ${name} | 相应命名捕获匹配的文本 |
| $‘ | 匹配位置之前的目标字符串文本 |
| $’ | 匹配位置之后的目标字符串文本 |
| $$ | 单个 $ 字符 |
| $R | 整个原始目标字符串的副本 |
| $+ | (见下文说明) |

$+ 序列目前的实现用处不大。它源于 Perl 中有用的 $+ 变量,该变量引用实际参与匹配的编号最高的捕获括号组。但在 .NET 替换字符串中, $+ 仅引用正则表达式中编号最高的捕获括号组,特别是在使用命名捕获时会自动重新编号,这使得它更显得无用。

除了表中描述的情况,替换字符串中其他对 $ 的使用不会被修改。

1.2 使用替换委托

替换参数不限于简单字符串,还可以是委托(本质上是函数指针)。委托函数在每次匹配后被调用,以生成用于替换的文本。由于函数可以进行任意处理,因此这是一种非常强大的替换机制。

委托类型为 MatchEvaluator ,每次匹配调用一次。它引用的函数应接受匹配的 Match 对象,进行所需的处理,并返回用于替换的文本。

以下是两个产生相同结果的代码片段示例:

Target = R.Replace(Target, "<<$&>>")

Function MatchFunc(ByVal M as Match) as String
    return M.Result("<<$&>>")
End Function
Dim Evaluator as MatchEvaluator = New MatchEvaluator(AddressOf MatchFunc)
Target = R.Replace(Target, Evaluator)

这两个代码片段都通过将匹配文本用 <<...>> 包裹来突出显示每个匹配。使用委托的优势在于,在计算替换内容时可以包含任意复杂的代码。例如,将摄氏度转换为华氏度的示例:

Function MatchFunc(ByVal M as Match) as String
    'Get numeric temperature from $1, then convert to Fahrenheit
    Dim Celsius as Double = Double.Parse(M.Groups(1).Value)
    Dim Fahrenheit as Double = Celsius * 9 / 5 + 32
    Return Fahrenheit & "F" 'Append an "F", and return
End Function
Dim Evaluator as MatchEvaluator = New MatchEvaluator(AddressOf MatchFunc)
Dim RRTemp as Regex = New Regex("(\d+)C\b", RegexOptions.IgnoreCase)
Target = RRTemp.Replace(Target, Evaluator)

若 Target 为 Temp is 37C. ,则会将其替换为 Temp is 98.6F. 。

2. 正则分割方法

2.1 基本分割

RegexObj.Split 方法将对象的正则表达式应用于目标字符串,返回由匹配项分隔的字符串数组。例如:

Dim R as New Regex("\.")
Dim Parts as String() = R.Split("209.204.146.22")

R.Split 返回由四个字符串 ('209', '204', '146', '22') 组成的数组,这些字符串由文本中 \. 的三次匹配分隔。

2.2 带计数的分割

如果提供了 count 参数,则返回的字符串数量不超过 count (除非使用了捕获括号,稍后会详细说明)。若未提供 count , Split 会返回由匹配分隔的尽可能多的字符串。提供 count 可能意味着正则表达式在最后一次匹配之前停止应用,此时最后一个字符串包含该行未分割的剩余部分。例如:

Dim R as New Regex("\.")
Dim Parts as String() = R.Split("209.204.146.22", 2)

此时, Parts 接收两个字符串 '209' 和 '204.146.22' 。

2.3 带偏移量的分割

如果提供了偏移量(整数),在尝试应用正则表达式之前会跳过目标字符串中的相应字符数。跳过的文本成为返回的第一个字符串的一部分(除非指定了 RegexOptions.RightToLeft ,此时跳过的文本成为返回的最后一个字符串的一部分)。

2.4 使用捕获括号进行分割

如果使用了任何类型的捕获括号,通常会将捕获的文本的额外条目插入数组中。例如,要将 '2006-12-31' 或 '04/12/2007' 这样的字符串拆分为其组成部分,可以使用以下代码:

Dim R as New Regex("[-/]")
Dim Parts as String() = R.Split(MyDate)

这将返回三个数字(作为字符串)的列表。然而,添加捕获括号并使用 ([-/,]) 作为正则表达式会使 Split 返回五个字符串。如果 MyDate 包含 '2006-12-31' ,则这些字符串为 '2006' , '-' , '12' , '-' , '31' 。额外的 '-' 元素来自每次捕获的 $1 。

如果有多个捕获括号组,它们将按数字顺序插入(这意味着所有命名捕获都在所有未命名捕获之后)。

只要所有捕获括号组都实际参与匹配, Split 与捕获括号的配合就能正常工作。但当前版本的 .NET 存在一个 bug,如果有一组捕获括号未参与匹配,则该组及其编号更高的组不会向返回列表中添加元素。

例如,想要按逗号及其周围的可选空格进行分割,并将空格添加到返回的元素列表中,可以使用 (\s+)?,(\s+)? 。当应用于 'this , that' 时,返回四个字符串 'this' , ' ' , ' ' , 'that' 。但当应用于 'this, that' 时,第一组捕获括号无法匹配,会阻止为其(以及后续所有组)添加元素到列表中,因此只返回两个字符串 'this' 和 'that' 。目前的实现无法预先确切知道每次匹配将返回多少个字符串,这是一个主要缺点。在这个特定示例中,可以通过使用 (\s+),(\s+) 来解决问题(在这种情况下,两个组都保证参与任何整体匹配),但更复杂的表达式则不容易重写。

3. 查询正则表达式信息的方法

3.1 查询捕获组信息

以下方法允许查询正则表达式中捕获组的名称(包括数字名称和命名捕获的名称):
- RegexObj.GetGroupNames()
- RegexObj.GetGroupNumbers()
- RegexObj.GroupNameFromNumber(number)
- RegexObj.GroupNumberFromName(name)

这些方法不涉及任何特定匹配,仅涉及正则表达式中存在的组的名称和编号。

3.2 查询 Regex 对象本身的信息

以下方法允许查询 Regex 对象本身的信息(而不是将正则表达式对象应用于字符串):
- RegexObj.ToString() :返回最初传递给正则表达式构造函数的模式字符串。
- RegexObj.RightToLeft :返回一个布尔值,指示是否在正则表达式中指定了 RegexOptions.RightToLeft 。
- RegexObj.Options :返回与正则表达式关联的 RegexOptions 。各个选项的值如下表所示,报告时会将它们相加:
| 值 | 选项 |
| ---- | ---- |
| 0 | None |
| 16 | Singleline |
| 1 | IgnoreCase |
| 32 | IgnorePatternWhitespace |
| 2 | Multiline |
| 64 | RightToLeft |
| 4 | ExplicitCapture |
| 256 | ECMAScript |
| 8 | Compiled |

缺失的 128 值是用于 Microsoft 调试选项,在最终产品中不可用。

以下代码展示了如何显示 Regex 对象的相关信息:

'Display information known about the Regex object in the variable R
Console.WriteLine("Regex is: " & R.ToString())
Console.WriteLine("Options are: " & R.Options)
If R.RightToLeft
    Console.WriteLine("Is Right-To-Left: True")
Else
    Console.WriteLine("Is Right-To-Left: False")
End If
Dim S as String
For Each S in R.GetGroupNames()
    Console.WriteLine("Name """ & S & """ is Num #" & R.GroupNumberFromName(S))
Next
Console.WriteLine("---")
Dim I as Integer
For Each I in R.GetGroupNumbers()
    Console.WriteLine("Num #" & I & " is Name """ & R.GroupNameFromNumber(I) & """")
Next

运行两次,分别使用以下两个 Regex 对象:

New Regex("ˆ(\w+)://([ˆ/]+)(/\S+)")
New Regex("ˆ(?<proto>\w+)://(?<host>[ˆ/]+)(?<page>/\S+)", RegexOptions.Compiled)

会产生以下输出(为适应页面,其中一个正则表达式被截断):

Regex is: ˆ(\w+)://([ˆ/]+)(/\S+)
Option are: 0
Is Right-To-Left: False
Name "0" is Num #0
Name "1" is Num #1
Name "2" is Num #2
Name "3" is Num #3
---
Num #0 is Name "0"
Num #1 is Name "1"
Num #2 is Name "2"
Num #3 is Name "3"
Regex is: ˆ(?<proto>\w+)://(?<host> ⋅⋅⋅
Option are: 8
Is Right-To-Left: False
Name "0" is Num #0
Name "proto" is Num #1
Name "host" is Num #2
Name "page" is Num #3
---
Num #0 is Name "0"
Num #1 is Name "proto"
Num #2 is Name "host"
Num #3 is Name "page"

4. 使用 Match 对象

Match 对象由 Regex 的 Match 方法、 Regex.Match 静态函数(稍后讨论)以及 Match 对象自身的 NextMatch 方法创建。它封装了与正则表达式单次应用相关的所有信息,具有以下属性和方法:

4.1 基本属性

  • MatchObj.Success :返回一个布尔值,指示匹配是否成功。若不成功,对象是静态 Match.Empty 对象的副本。
  • MatchObj.Value 和 MatchObj.ToString() :返回实际匹配的文本副本。
  • MatchObj.Length :返回实际匹配文本的长度。
  • MatchObj.Index :返回一个整数,指示在目标文本中找到匹配的位置。它是基于零的索引,即从字符串开头(左侧)到匹配文本开头(左侧)的字符数,即使使用 RegexOptions.RightToLeft 创建生成此 Match 对象的正则表达式,该规则仍然适用。

4.2 分组属性

MatchObj.Groups 属性是一个 GroupCollection 对象,其中封装了多个 Group 对象。它是一个普通的集合对象,具有 Count 和 Item 属性,但最常见的访问方式是通过索引获取单个 Group 对象。例如, M.Groups(3) 是与第三组捕获括号相关的 Group 对象, M.Groups("HostName") 是 “Hostname” 命名捕获的组对象(例如,在正则表达式中使用 (?<HostName>...) 之后)。需要注意的是,C# 中需要使用 M.Groups[3] 和 M.Groups["HostName"] 。第 0 组表示整个匹配本身,例如, MatchObj.Groups(0).Value 与 MatchObj.Value 相同。

4.3 其他方法

  • MatchObj.NextMatch() :重新调用原始正则表达式以在原始字符串中查找下一个匹配,返回一个新的 Match 对象。
  • MatchObj.Result(string) :处理给定字符串中的特殊序列,返回处理后的文本。例如:
Dim M as Match = Regex.Match(SomeString, "\w+")
Console.WriteLine(M.Result("The first word is ’$&’"))

可以使用它获取匹配左右的文本副本:

M.Result("$‘") '这是匹配左侧的文本
M.Result("$’") '这是匹配右侧的文本

在调试时,显示类似 M.Result("[$‘<$&>$’]") 的内容可能会有帮助。例如,将 \d+ 应用于字符串 'May 16, 1998' 创建的 Match 对象,会返回 'May <16>, 1998' ,清晰显示了确切的匹配。
- MatchObj.Synchronized() :返回一个新的 Match 对象,与当前对象相同,但可安全用于多线程。
- MatchObj.Captures 属性不常使用,从第 437 页开始讨论。

5. 使用 Group 对象

Group 对象包含一组捕获括号的匹配信息(如果是第 0 组,则表示整个匹配)。它具有以下属性和方法:

5.1 基本属性

  • GroupObj.Success :返回一个布尔值,指示该组是否参与了匹配。并非所有组都一定会参与成功的整体匹配。例如,若 (this)<(that) 匹配成功,其中一组括号保证参与匹配,而另一组则保证未参与。
  • GroupObj.Value 和 GroupObj.ToString() :返回该组捕获的文本副本。若匹配不成功,返回空字符串。
  • GroupObj.Length :返回该组捕获的文本长度。若匹配不成功,返回 0。
  • GroupObj.Index :返回一个整数,指示在目标文本中找到该组匹配的位置。返回值是基于零的索引,即从字符串开头(左侧)到捕获文本开头(左侧)的字符数,即使使用 RegexOptions.RightToLeft 创建生成此 Match 对象的正则表达式,该规则仍然适用。
  • GroupObj.Captures 属性从第 437 页开始讨论。

6. 静态“便利”函数

在正则表达式的使用中,并不总是需要显式创建 Regex 对象。以下静态函数允许直接应用正则表达式:
- Regex.IsMatch(target, pattern)
- Regex.IsMatch(target, pattern, options)
- Regex.Match(target, pattern)
- Regex.Match(target, pattern, options)
- Regex.Matches(target, pattern)
- Regex.Matches(target, pattern, options)
- Regex.Replace(target, pattern, replacement)
- Regex.Replace(target, pattern, replacement, options)
- Regex.Split(target, pattern)
- Regex.Split(target, pattern, options)

这些函数本质上是对我们已经看到的核心 Regex 构造函数和方法的包装。它们为你构造一个临时的 Regex 对象,使用它调用你请求的方法,然后丢弃该对象(实际上并非真正丢弃,稍后会详细说明)。

例如:

If Regex.IsMatch(Line, "ˆ\s+$")

这与以下代码相同:

Dim TemporaryRegex = New Regex("ˆ\s+$")
If TemporaryRegex.IsMatch(Line)

或者更准确地说,与以下代码相同:

If New Regex("ˆ\s+$").IsMatch(Line)

使用这些便利函数的优点是,它们通常使简单任务更轻松、更便捷,使面向对象的包看起来像过程式的。缺点是每次都必须重新检查模式。

如果正则表达式在整个程序执行过程中只使用一次,从效率角度来看,使用便利函数与否无关紧要。但如果正则表达式多次使用(例如在循环中或常用函数中),每次准备正则表达式都会有一些开销。避免这种通常昂贵的开销是构建一次 Regex 对象,然后在实际检查文本时反复使用它的主要原因。不过,.NET 提供了一种两全其美的方法:兼具过程式的便利和面向对象的效率。

7. 正则表达式缓存

每次使用小的正则表达式都要构建和管理一个单独的 Regex 对象可能会很繁琐和不便,因此 .NET 正则表达式包提供了各种静态方法,这是非常好的。然而,静态方法的一个效率缺点是,理论上每次调用都会为你创建一个临时的 Regex 对象,应用它,然后丢弃它。在循环中多次对同一正则表达式执行此操作可能会有很多冗余工作。

为避免重复工作,.NET Framework 为通过静态方法创建的临时对象提供了缓存。一般来说,缓存的相关内容在第 6 章讨论,但简而言之,如果在静态方法中使用的正则表达式与“最近”使用的相同,静态方法将重用之前创建的正则表达式对象,而不是从头开始构建一个新的。

“最近”的默认含义是最近的 15 个正则表达式会被缓存。如果在循环中使用超过 15 个正则表达式,缓存的好处就会丧失,因为第 16 个正则表达式会挤出第一个,这样当你重新启动循环并重新应用时,第一个正则表达式已不在缓存中,必须重新生成。

如果默认的 15 个的大小对你来说太小,可以进行调整:

Regex.CacheSize = 123

如果你想禁用所有缓存,可以将值设置为 0。

8. 支持函数

除了前面讨论的便利函数外,还有一些其他的静态支持函数:

8.1 Regex.Escape

Regex.Escape(string) 函数接受一个字符串,返回一个将正则表达式元字符转义后的副本。这使得原始字符串适合作为文字字符串包含在正则表达式中。例如,如果用户输入存储在字符串变量 SearchTerm 中,可以使用以下代码构建正则表达式:

Dim UserRegex as Regex = New Regex("ˆ" & Regex.Escape(SearchTerm) & "$", RegexOptions.IgnoreCase)

这允许搜索词包含正则表达式元字符,而不会将它们视为元字符。如果不进行转义,例如 SearchTerm 的值为 ':-)' ,会抛出 ArgumentException 。

8.2 Regex.Unescape

Regex.Unescape(string) 函数接受一个字符串,返回一个解释了某些正则表达式字符转义序列并移除其他反斜杠的副本。例如,如果传入 '\:\-\)' ,它将返回 ':-)' 。字符简写也会被解码。如果原始字符串中有 '\n' ,在返回的字符串中实际上会被替换为换行符。或者如果有 '\u1234' ,相应的 Unicode 字符将被插入到字符串中。第 407 页顶部列出的所有字符简写都会被解释。虽然很难想象 Regex.Unescape 在正则表达式相关方面有很好的用途,但它可能作为一个通用工具,为 VB 字符串赋予一些转义知识。

8.3 Match.Empty

Match.Empty 函数返回一个表示匹配失败的 Match 对象。它可能用于初始化一个 Match 对象,该对象可能会也可能不会在稍后填充,但确实打算稍后查询。例如:

Dim SubMatch as Match = Match.Empty 'Initialize, in case it’s not set in the loop below
Dim Line as String
For Each Line in EmailHeaderLines
    'If this is the subject, save the match info for later...
    Dim ThisMatch as Match = Regex.Match(Line, "ˆSubject:\s+(.+)", RegexOptions.IgnoreCase)
    If ThisMatch.Success
        SubMatch = ThisMatch
    End If
Next
If SubMatch.Success
    Console.WriteLine(SubMatch.Result("The subject is: $1"))
Else
    Console.WriteLine("No subject!")
End If

如果字符串数组 EmailHeaderLines 实际上没有行(或没有主题行),遍历它们的循环将永远不会设置 SubMatch ,因此如果没有以某种方式初始化,循环后对 SubMatch 的检查将导致空引用异常。所以,在这种情况下使用 Match.Empty 作为初始化器很方便。

8.4 Regex.CompileToAssembly

Regex.CompileToAssembly(...) 允许创建一个封装 Regex 对象的程序集,具体内容见下一节。

综上所述,.NET 中的正则表达式功能丰富且强大,通过合理使用这些方法和特性,可以高效地处理各种文本匹配和替换任务。同时,要注意一些细节,如捕获括号在分割时的使用以及缓存的设置,以避免潜在的问题和提高性能。

9. 总结与注意事项

9.1 功能总结

在 .NET 中使用正则表达式,我们拥有了丰富的工具和方法来处理文本匹配、替换和分割等任务。以下是对主要功能的总结:
- 替换功能 :通过 Regex.Replace 方法和 Match.Result 方法,可以实现强大的替换操作,支持特殊替换序列,还能使用替换委托进行复杂的替换处理。
- 分割方法 : RegexObj.Split 方法可将目标字符串按正则匹配进行分割,支持带计数、偏移量以及捕获括号的分割。
- 信息查询 :提供了多种方法用于查询正则表达式中捕获组的信息以及 Regex 对象本身的信息。
- 对象使用 : Match 对象和 Group 对象封装了匹配和分组的详细信息,方便我们获取和处理匹配结果。
- 静态便利函数 :一系列静态函数让简单的正则操作更加便捷,但多次使用同一正则表达式时可能存在效率问题。
- 缓存机制 :.NET 为静态方法创建的临时对象提供了缓存,可避免重复创建正则对象的开销。
- 支持函数 :包括 Regex.Escape 、 Regex.Unescape 、 Match.Empty 和 Regex.CompileToAssembly 等,为正则表达式的使用提供了更多便利和扩展。

9.2 注意事项

在使用这些功能时,需要注意以下几点:
- 捕获括号问题 :在使用 Split 方法时,若使用捕获括号,要注意当前版本 .NET 存在的 bug,即部分捕获括号未参与匹配时可能影响返回结果。对于复杂表达式,重写以解决此问题可能并不容易。
- 缓存设置 :正则表达式缓存的默认大小为 15 个,若在循环中使用的正则表达式数量超过此值,缓存将失效。可根据实际情况调整缓存大小或禁用缓存。
- 性能考虑 :对于多次使用的正则表达式,建议构建一次 Regex 对象并反复使用,以避免每次准备正则表达式的开销。

10. 实际应用示例

为了更好地理解和应用上述知识,下面给出一些实际应用示例。

10.1 验证邮箱地址

我们可以使用正则表达式来验证一个字符串是否为有效的邮箱地址。示例代码如下:

Dim emailPattern As String = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
Dim emailRegex As New Regex(emailPattern)
Dim email As String = "example@example.com"
If emailRegex.IsMatch(email)
    Console.WriteLine("Valid email address.")
Else
    Console.WriteLine("Invalid email address.")
End If

在这个示例中,我们定义了一个邮箱验证的正则表达式模式,创建了 Regex 对象,然后使用 IsMatch 方法验证邮箱地址是否有效。

10.2 提取 HTML 标签中的内容

假设我们有一个 HTML 字符串,想要提取其中所有 <p> 标签内的内容。示例代码如下:

Dim html As String = "<html><body><p>First paragraph</p><p>Second paragraph</p></body></html>"
Dim htmlPattern As String = "<p>(.*?)</p>"
Dim htmlRegex As New Regex(htmlPattern, RegexOptions.IgnoreCase)
Dim matches As MatchCollection = htmlRegex.Matches(html)
For Each match As Match In matches
    Console.WriteLine(match.Groups(1).Value)
Next

在这个示例中,我们使用 Matches 方法查找所有匹配的 <p> 标签,并通过 Groups(1) 获取标签内的内容。

10.3 格式化电话号码

假设我们有一个包含电话号码的字符串,格式可能不统一,我们想要将其格式化为统一的 (XXX) XXX-XXXX 格式。示例代码如下:

Function FormatPhoneNumber(ByVal M As Match) As String
    Dim phoneNumber As String = M.Value
    phoneNumber = phoneNumber.Replace("-", "").Replace(" ", "").Replace("(", "").Replace(")", "")
    Return String.Format("({0}) {1}-{2}", phoneNumber.Substring(0, 3), phoneNumber.Substring(3, 3), phoneNumber.Substring(6))
End Function
Dim phonePattern As String = "\d{3}[-\s]?\d{3}[-\s]?\d{4}"
Dim phoneRegex As New Regex(phonePattern)
Dim phoneText As String = "123-456-7890 123 456 7890 (123)4567890"
Dim evaluator As New MatchEvaluator(AddressOf FormatPhoneNumber)
Dim formattedText As String = phoneRegex.Replace(phoneText, evaluator)
Console.WriteLine(formattedText)

在这个示例中,我们使用替换委托 MatchEvaluator 来实现电话号码的格式化。

11. 流程图示例

下面是一个简单的流程图,展示了使用正则表达式进行文本匹配和替换的基本流程:

graph TD;
    A[开始] --> B[定义正则表达式模式];
    B --> C[创建 Regex 对象];
    C --> D[选择操作类型];
    D --> |匹配| E[使用 IsMatch 或 Match 方法];
    D --> |替换| F[使用 Replace 方法];
    D --> |分割| G[使用 Split 方法];
    E --> H{匹配成功?};
    H --> |是| I[处理匹配结果];
    H --> |否| J[结束];
    F --> K[获取替换结果];
    G --> L[获取分割后的数组];
    I --> J;
    K --> J;
    L --> J;
    J[结束];

这个流程图清晰地展示了在 .NET 中使用正则表达式的基本步骤,从定义模式到选择操作类型,再到处理结果,最后结束流程。

12. 总结与展望

通过本文的介绍,我们深入了解了 .NET 中正则表达式的各种功能和使用方法。正则表达式在文本处理中具有重要的作用,能够帮助我们高效地完成各种匹配、替换和分割任务。在实际应用中,我们要根据具体需求选择合适的方法和工具,并注意一些细节和性能问题。

随着技术的不断发展,正则表达式的应用场景也在不断扩大。未来,我们可以期待 .NET 对正则表达式的支持更加完善,提供更多的功能和优化,以满足更复杂的文本处理需求。同时,开发者也可以结合其他技术和工具,进一步拓展正则表达式的应用范围,创造出更加高效和强大的文本处理程序。

希望本文能够帮助你更好地掌握 .NET 中正则表达式的使用,在实际开发中更加得心应手地处理文本任务。如果你有任何疑问或建议,欢迎留言讨论。

相关推荐

2025 年国人友好神刊盘点:20 本审稿快、分区高的 SCI 期刊,速抢发文先机!

科睿唯安最新发布的 2024 年影响因子(2025 年公布)显示,多本 TOP 期刊影响因子迎来大幅上涨!尤其是对国人友好的期刊,因审稿效率高、版面费亲民、国人发文占比超 40%,成为科研人员投稿热门。本文精选 20 本潜力神刊,涵盖Cell 子刊、顶流期刊、黑马期刊、性价比之王及新晋分区 TOP,附完整的影响因子、中科院分区、审稿周期、收稿方向攻略,助你抢占发文先机!

good_rrrrr的博客 5560

GD32F303开发实战(一):从零搭建MDK工程与时钟配置详解

本文详细介绍了如何从零开始为GD32F303微控制器搭建一个清晰、可维护的MDK工程模板。内容涵盖开发环境准备、工程目录结构规划、文件分组管理、关键工程配置,并重点解析了时钟树原理,手把手指导配置108MHz系统时钟。通过实战步骤与常见问题排查,帮助开发者构建一个稳定可靠的开发基础,便于后续功能扩展。

weixin_29174141的博客 271

【processing】创意编程

首先接到这个作业的时候,我是很崩溃的,我是真的不会画画QAQ,还画自己,这也太难了,于是我决定!还是祸害我爱豆吧!于是我从微博太太那里找了个图临摹 下面是太太的图 先给太太道歉!都是为了作业! 然后我画出来是这样子的 还可以!!!没有特别丑!(虽然也不是特别像吧) 但是画这个真是画死我了,下面贴上代码吧,没啥特殊的就是各种贝塞尔曲线各种圆各种线 //face stroke(70,27,11...

qq_25700571的博客 1267

SOC设计必看!Tessent DRC检查中最容易踩的5个坑(附解决方案)

本文针对SOC设计中Tessent DRC检查的常见问题,详细分析了5个最易忽视的陷阱,包括时钟域交叉、扫描链虚连、多电压域规则等,并提供专业解决方案。特别针对芯片设计中的DFT验证难点,分享了经过验证的调试方法和Tessent工具使用技巧,帮助工程师提升DRC检查效率。

weixin_29280657的博客 496

Unreal5 从入门到精通之 如何实现 离线语音识别

本文介绍了如何使用离线语音识别插件 Offline Speech Recognition 进行本地语音转文本处理。该插件支持离线运行,用户可以通过下载并运行语言服务器(如 Vosk)来处理语音数据。文章详细说明了如何设置语言服务器、下载语言模型,并在虚幻引擎(UE)项目中配置麦克风和语音捕获。此外,还介绍了如何将 SoundWave 作为输入,以及如何通过节点将语音数据发送到语言服务器进行处理。最后,提供了相关文档链接以供进一步参考。

TxNet 906

《C#零基础入门之百识百例》(七十一)委托介绍 -- 战士升级示例

委托的存在是因为,我们有时候需要将一个函数作为另一个函数的参数,这时就要用的委托(Delegate)机制。委托用关键字`delegate`声明,他实际上定义了一种“函数类型”,明确规定了函数参数类型和返回值类型。

陈言必行 -- Unity游戏开发领域优质博主 2111

SIMULINK开发项目实例 1000 例专栏之第847例--基于飞行控制与稳定性的场景实例:多旋翼无人机在风扰动下的稳定性分析

本文介绍了使用Simulink进行多旋翼无人机风扰动稳定性分析的完整流程。首先建立包含动力学模型、控制系统和环境模拟三大模块的仿真系统,其中动力学模型基于牛顿-欧拉方程,控制系统采用PID调节器。重点展示了MATLAB函数实现的风扰动模型和姿态控制算法,通过设置输入信号和输出显示模块完成闭环仿真。最后通过多次风速条件下的仿真测试评估控制系统的抗干扰能力和稳定性表现,为无人机控制系统设计提供了有效的仿真验证方法。

xiaoheshang_123的博客 322

lammps教程:FeNiCr合金多晶结构建模方法

大家好,我是小马老师。 本文介绍合金多晶模型的建模过程,使用的软件为Atomsk。 Atomsk是一个开源软件,可运行在windows、linux等多种操作系统上,本文使用windows版的Atomsk实现建模,其他操作系统的建模命令基本相同。 建模过程如下: 1. 生成单晶Fe晶胞 atomsk --create fcc 3.65 Fe Fe.xsf 2. 建立多晶节点文件polycrystal.txt 新建一个文本文件polycrystal.txt,文件内容为: box 200 100 200 ran

lammps_jiayou的博客 6658

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: 6、机器学习模型可解释性方法及逻辑回归模型解析
下一篇: 28、拍卖机制策略防策略性的抽象与验证
bean
博客等级 码龄27年 1454粉丝 1637原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值