jregex:用正则表达式快速实现匹配和替换

文摘   教育   2024-10-29 22:00   山西  

👇 连享会 · 推文导航 | www.lianxh.cn

🍓 课程推荐:2024 机器学习与因果推断专题
主讲老师:司继春 (上海对外经贸大学) ;张宏亮(浙江大学)
课程时间:2024 年 11 月 9-10 日 ;16-17日
课程咨询:王老师 18903405450(微信)

课程特色 · 2024机器学习与因果推断

  • 懂原理、会应用。本次课程邀请了两位老师合作讲授,目的在于最大限度地实现理论与应用的有机结合。为期四天的课程,分成两个部分:第一部分讲解常用的机器学习算法和适用条件,以及文本分析和大语言模型;第二部分通过精讲 4-6 篇发表于 Top 期刊的论文,帮助大家理解各类机器学习算法的应用场景,以及它们与传统因果推断方法的巧妙结合。
  • 以 Top 期刊论文为范例。目前多数人的困惑是不清楚如何将传统因果推断方法与机器学习结合起来。事实上,即便是 MIT 和 Harvard 的大牛们也都在「摸着石头过河」。为此,通过论文精讲和复现来学习这部分内容或许是目前最有效的方式了。张宏亮老师此前在浙江大学按照这一模式教授了「因果推断和机器学习」课程,效果甚佳:学生们能够逐渐建立起研究设计的理念,并在构造识别策略时适当地嵌入机器学习方法。

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:

作者: 汪京 (兰州大学)
邮箱: wang_jing20@163.com

   

1. 引言

正则匹配与正则替换是数据清洗或文本分析工作中的重要组成部分, Stata 中的一些命令 ( regexmregexsregexrustrregexmustrregexs 等 ) 可以虽然完成这些工作,但这些命令仍有局限,例如不支持 Dotall 模式,这会给正则匹配与替换带来许多不便。William Buchanan 开发了 jregex 命令,该命令与 Stata 中的本机正则表达式函数不同,使用 Java 中提供的正则表达式功能。该命令和 Stata 中的本机函数工作方式之间的最大区别是能够使用 POSIX 字符类 ( 例如:\p{Alpha}, \p{Punct}, 等等)、Dotall 模式以及 Java 中提供的其他一些功能。Pattern API Javadocs 中包括有关Java实现正则表达式的更多信息。下文将介绍 jregex 命令,并给出几个范例。

2. 命令安装

本外部命令的发布者将安装包上传到了 Github ,我们可以在 Stata 中输入以下命令来安装 jregex

** 从 Github 安装命令
net install jregex, from("http://wbuchanan.github.io/StataRegex/")

安装完成后,可以输入 help jregex 查看具体用法。

3. 命令介绍

jregex 是一个基于 Java 的插件,用于 Stata 中的正则表达式。jregex 命令可以实现 Stata 与 Java 的交互,通过 Stata 调用 Java 中的正则表达式。jregex 的语法结构如下:

其中,

  • subcommand 为子命令,目前 jregex 只支持 replace 一种子命令,代表正则替换命令;
  • varnameexisting string variable 为数据中的字符串变量名;
  • newvarto store altered values 为正则替换后新生成的变量名,如不指定此参数,则执行正则替换后会覆盖原变量;
  • pattern(string) 为匹配文本使用的正则表达式。可用的正则表达式请查阅此 Java 官方文档,或如下连享会推文:
    • 孙晓艺, 2024, 文本分析:正则表达式之位置匹配, 连享会 No.1350.
    • 梁淑珍, 2022, Stata:正则表达式教程, 连享会 No.968.
    • 游万海, 2020, Stata: 正则表达式和文本分析, 连享会 No.35.
    • 连享会, 2020, 在 Visual Studio (vsCode) 中使用正则表达式, 连享会 No.10.
    • 连享会, 2020, 正则表达式语言 - 快速参考, 连享会 No.81.

[ options ] 中的其它选项包括:

  • canon :启用正则等价。
  • insensitive :启用不区分大小写的匹配。
  • comments :允许在正则表达式中使用空格和注释。
  • dotall :启用 Dotall 模式,该模式下,元字符 . 可以匹配任意单个字符,包括换行符和回车符。
  • literal :启用正则表达式的文本解析。
  • multiline :启用 multiline 模式,该模式下,即使正则表达式里出现了 ^$,也会匹配所有行。
  • unicase :启用此模式时,当 insensitive 模式启用时,将以与 Unicode 标准一致的方式进行不区分大小写的匹配。默认情况下,不区分大小写的匹配假定只匹配 US-ASCII 字符集中的字符。
  • uniclass :启用 Predefined 字符类和 POSIX 字符类的 Unicode 版本。
  • unixlines :启用 Unix lines 模式。
  • noanchor :对 Matcher类对象 使用透明边界而不是锚定边界。
  • replace(string) :用来替代匹配值的字符串。
  • repfirst :指定该选项后,仅替换第一个匹配值。

4. 使用范例

下面介绍几个使用 jregex 命令进行正则匹配与正则替换的范例:

首先,导入字符串作为范例:

** 导入字符串变量,命名为 addy
input str55 addy
"6675,+Old+Canton+RD,+Ridgeland,+MS,+39157"
"12313,+33RD+Ave+Nort,+SEATTLE,+wa,+98125"
"310,+Cahir+StreeT,+Providence,+Rhode+Island,+02903"
"22,+Oaklawn+Ave,+Cranston,+RI,+02920"
"61,+pine+st,+Attleboro,+MA,+02703"
"10,+larkspur+R0ad,+Warwick,+ri,+02886"
"91,+FaLLon+Ave,+Providence,+RI,+02908"
"195,+Arlington+AVE,+Providence,+RI,+02906"
"74,+REGENT+aVenuE,+Providence,+RI,+02908"
end

4.1 使用正则表达式替换字符串,并覆盖原变量

在 Stata 中输入以下代码,可以将 addy 变量下各字符串中出现的第一个 + 替换为 _this is a replacement string_

** 使用jregex命令进行正则替换
jregex replace addy, repf ///
p(`"\+"') ///
rep(`"_this is a replacement string_"')

** 查看正则替换后的结果
list

+--------------------------------------------------------------------------------+
| addy |
|--------------------------------------------------------------------------------|
1. | 6675,_this is a replacement string_Old+Canton+RD,+Ridgeland,+MS,+39157 |
2. | 12313,_this is a replacement string_33RD+Ave+Nort,+SEATTLE,+wa,+98125 |
3. | 310,_this is a replacement string_Cahir+StreeT,+Providence,+Rhode+Island,+02.. |
4. | 22,_this is a replacement string_Oaklawn+Ave,+Cranston,+RI,+02920 |
5. | 61,_this is a replacement string_pine+st,+Attleboro,+MA,+02703 |
|--------------------------------------------------------------------------------|
6. | 10,_this is a replacement string_larkspur+R0ad,+Warwick,+ri,+02886 |
7. | 91,_this is a replacement string_FaLLon+Ave,+Providence,+RI,+02908 |
8. | 195,_this is a replacement string_Arlington+AVE,+Providence,+RI,+02906 |
9. | 74,_this is a replacement string_REGENT+aVenuE,+Providence,+RI,+02908 |
+--------------------------------------------------------------------------------+

4.2 使用正则表达式替换字符串,并另存为新变量

在 Stata 中输入以下代码,可以将 addy 变量下各字符串中的 _this is a replacement string_ 替换为 +  ,并将替换结果另存为 newaddy 变量。

** 使用jregex命令进行正则替换
jregex replace addy newaddy, p(`"_this is a replacement string_"') rep(`"\+"')
** 查看正则替换后的结果
list newaddy

+----------------------------------------------------+
| newaddy |
|----------------------------------------------------|
1. | 6675,+Old+Canton+RD,+Ridgeland,+MS,+39157 |
2. | 12313,+33RD+Ave+Nort,+SEATTLE,+wa,+98125 |
3. | 310,+Cahir+StreeT,+Providence,+Rhode+Island,+02903 |
4. | 22,+Oaklawn+Ave,+Cranston,+RI,+02920 |
5. | 61,+pine+st,+Attleboro,+MA,+02703 |
|----------------------------------------------------|
6. | 10,+larkspur+R0ad,+Warwick,+ri,+02886 |
7. | 91,+FaLLon+Ave,+Providence,+RI,+02908 |
8. | 195,+Arlington+AVE,+Providence,+RI,+02906 |
9. | 74,+REGENT+aVenuE,+Providence,+RI,+02908 |
+----------------------------------------------------+

4.3 使用 POSIX 字符类正则表达式替换字符串

在 Stata 中输入以下代码,可以将 newaddy 变量下各字符串中的每个标点符号替换为一个空格。

** 使用jregex命令进行正则替换
jregex replace newaddy, p(`"\p{Punct}"') rep(" ")
** 查看正则替换后的结果
list newaddy

+----------------------------------------------------+
| newaddy |
|----------------------------------------------------|
1. | 6675 Old Canton RD Ridgeland MS 39157 |
2. | 12313 33RD Ave Nort SEATTLE wa 98125 |
3. | 310 Cahir StreeT Providence Rhode Island 02903 |
4. | 22 Oaklawn Ave Cranston RI 02920 |
5. | 61 pine st Attleboro MA 02703 |
|----------------------------------------------------|
6. | 10 larkspur R0ad Warwick ri 02886 |
7. | 91 FaLLon Ave Providence RI 02908 |
8. | 195 Arlington AVE Providence RI 02906 |
9. | 74 REGENT aVenuE Providence RI 02908 |
+----------------------------------------------------+

4.4 使用 Dotall 模式正则表达式替换回车符和换行符

正如前文中提到的,默认情况下,元字符 . 不会匹配换行符和回车符,设置了 Dotall 模式后,其就会匹配所有字符包括换行符和回车符。但是 Stata 中的几个正则表达式字符串函数 ( regexmregexsregexrustrregexmustrregexs 等 ) 是不能使用 Dotall 模式的。此时, jregex 可以用 Dotall 模式很好地解决这个问题。

与前几个范例不同是的,本例需要重新构造字符串。在 Stata 中输入以下代码,可以在当前工作环境下创建新文本文件 "123.txt" 用于储存范例字符串。

** 在当前工作环境下创建新文本文件"123.txt"用于储存范例字符串
file open myfile using "123.txt", write replace
file write myfile `" <div id="box" > "' _n
file write myfile `" <div id="content"> "' _n
file write myfile `" <pre>"' _n
file write myfile `"连享会"' _n
file write myfile `"lianxh </pre> "' _n
file write myfile `" </div> "' _n
file write myfile `" <div style="clear:both"></div> "'
file close myfile

在 Stata 中输入以下代码,将字符串导入 Stata 数据中,并储存在变量 str 中。可以看到,此时的 str 中存在空格、换行符与回车符,并且 连享会lianxh 字符被 <pre></pre> 包围。假设我们想从此字符串中提取出 连享会lianxh 。首先,尝试使用 ustrregexra 进行正则替换,结果显示替换并不成功。

** 导入并查看字符串
clear
set more off
set obs 1
gen str = fileread("123.txt")
list
** 使用 ustrregexra 进行正则替换
replace str = ustrregexra(str,".+<pre>","")
replace str = ustrregexra(str,"</pre>.+","")
list
     +-------------------------------------------+
| str |
|-------------------------------------------|
1. | <div id="box" >
<div id="content">
<pre>
连.. |
+-------------------------------------------+

+-------------------------------------------+
| str |
|-------------------------------------------|
1. | <div id="box" >
<div id="content">

连享会
lianxh
.. |
+-------------------------------------------+

接下来,重新导入字符串范例,使用 jregex 进行正则替换,并指定 Dotall 模式。结果显示,目标被成功提取出来。

** 重新字符串
clear
set more off
set obs 1
gen str = fileread("123.txt")
** 使用 jregex 进行正则替换
jregex replace str ,p(".+<pre>") rep("") dotall
jregex replace str ,p("</pre>.+") rep("") dotall
jregex replace str ,p("\r\n") rep("")
compress
list
     +---------------+
| str |
|---------------|
1. | 连享会lianxh |
+---------------+

5. 结语

jregex 命令与 Stata 中的本机正则表达式函数不同,使用 Java 中提供的正则表达式功能。该命令能够使用 POSIX 字符类 ( 例如:\p{Alpha}, \p{Punct}, 等等)、Dotall 模式以及 Java 中提供的其他一些功能,为在 Stata 中实现正则匹配与替换带来了很大的便利。

6. 参考资料

  • Java Powered Regular Expressions
  • jregex for java
  • Statalist:New program for regular expressions
  • Stata Club:正则表达式之Dotall模式

7. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 正则
安装最新版 lianxh 命令:
ssc install lianxh, replace

  • 孙晓艺, 2024, 文本分析:正则表达式之位置匹配, 连享会 No.1350.
  • 李岸瑶, 2022, Word技巧:如何使用正则表达式高效替换, 连享会 No.890.
  • 梁淑珍, 2022, Stata:正则表达式教程, 连享会 No.968.
  • 游万海, 2020, Stata: 正则表达式和文本分析, 连享会 No.35.
  • 游万海, 2020, Stata爬虫-正则表达式:爬取必胜客, 连享会 No.287.
  • 游万海, 2021, 用正则表达式整理文献:正文与文末一一对应, 连享会 No.547.
  • 许梦洁, 2020, Python: 使用正则表达式从文本中定位并提取想要的内容, 连享会 No.91.
  • 连享会, 2020, 在 Visual Studio (vsCode) 中使用正则表达式, 连享会 No.10.
  • 连享会, 2020, 正则表达式语言 - 快速参考, 连享会 No.81.
  • 连玉君, 2021, 用VScode正则表达式转换Markdown和LaTeX链接, 连享会 No.839.

🍓 课程推荐:2024 机器学习与因果推断专题
主讲老师:司继春 (上海对外经贸大学) ;张宏亮(浙江大学)
课程时间:2024 年 11 月 9-10 日 ;16-17日
课程咨询:王老师 18903405450(微信)

尊敬的老师 / 亲爱的同学们:

连享会致力于不断优化和丰富课程内容,以确保每位学员都能获得最有价值的学习体验。为了更精准地满足您的学习需求,我们诚挚地邀请您参与到我们的课程规划中来。请您在下面的问卷中,分享您 感兴趣的学习主题或您希望深入了解的知识领域 。您的每一条建议都是我们宝贵的资源,将直接影响到我们课程的改进和创新。我们期待您的反馈,因为您的参与和支持是我们不断前进的动力。感谢您抽出宝贵时间,与我们共同塑造更加精彩的学习旅程!https://www.wjx.cn/vm/YgPfdsJ.aspx# 再次感谢大家宝贵的意见!

New! Stata 搜索神器:lianxhsongbl  GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉  使用:
. lianxh DID 倍分法
. songbl all

🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。

连享会
连玉君老师团队分享,主页:lianxh.cn。白话计量,代码实操;学术路上,与君同行。
 最新文章