java - 英语缩写灾难

标签 java regex text-parsing

背景

将直引号写入弯引号转换器,并希望将替换分成几个不同的步骤。第一步是使用已知缩写词词典替换文本中的缩写词。这不会解决歧义,但应该转换常见缩写中的直引号用法。

问题

在 Java 中,\b\w不要将撇号作为单词的一部分,这使得这个问题有点挑剔。问题在于匹配以下单词:

  • 包含一个或多个撇号,但不以一个(内部)开头或结尾;
  • 以撇号开头,可以包含一个或多个,但不能以一个撇号结尾(开始);
  • 以撇号结尾,可以包含一个或多个,但不能以一个开头(结束);和
  • 以撇号开头和结尾,但不得包含撇号(外部)。

代码

给出一些无意义的文本:

'Twas---Wha'? Wouldn'tcha'? 'Twas, or 'twasn't, 'tis what's 'tween dawn 'n' dusk 'n stuff. Cookin'? 'Sams' place, 'yo''

正则表达式应捕获以下单词:

  • 内部:what's
  • 开始:'Twas , 'Twas , 'twasn't , 'tis , 'tween , 'n
  • 结束:Wha' , Wouldn'tcha' , Cookin'
  • 外部:'n' , 'Sams' , 'yo'

以下是不起作用的表达方式,是拙劣想法的混合体:

  • 内部:\p{L}+'\p{L}*\p{L}
  • 开始:((?<=[^\p{L}])|^)'\p{L}+('\p{L}|\p{L})?
  • 结束:(\p{L}|\p{L}')+'(?=[^\p{L}]|$)

这个似乎有效:

  • 外部:((?<=[^\p{L}])|^)'\p{L}+'(?!\p{L})

问题

什么正则表达式可以正确地对这四个缩写进行分类?

最佳答案

这个正则表达式应该做你想要的。它使用命名捕获组通过适当的查找对单词进行分类,以确保我们将整个单词与所需的外引号相匹配:

(?<inner>(?<![\p{L}'])(?:\p{L}+')+\p{L}+(?![\p{L}']))|
(?<began>(?<!\p{L})(?:'\p{L}+)+(?![\p{L}']))|
(?<ended>(?<![\p{L}'])(?:\p{L}+')+(?!\p{L}))|
(?<outer>(?<!\p{L})'\p{L}+'(?!\p{L}))

Group inner 查找包含一定数量的字母组的字符串,后跟引号 (?:\p{L}+')+ 后跟一些数字字母 \p{L}+

Group began 查找包含若干组引号的字符串,后跟若干字母 (?:'\p{L}+)+

Group ending 查找包含一定数量的字母组并后跟引号 (?:\p{L}+')+ 的字符串。

Group outer 查找两端带有引号且中间包含一些字母的字符串 '\p{L}+'

Demo on regex101

关于java - 英语缩写灾难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67171786/

相关文章:

c++ - 那是 C++ 编译器错误吗?

powershell - 使用分隔符在Powershell中分割文件

ios - 将表示数字数组的数组的 NSString 转换为 NSArray

ruby - 在一行中查找不区分大小写的单词匹配项

正则表达式查找没有日志的捕获 block

python - 运行时之前的 SimpleParse 非确定性语法

java - 如何在java中获取系统日期和时间格式?

java - 插入数据后 响应提交后无法转发

java - 如何在本地主机上运行 JSP 网站?需要搭建什么环境?

java - 将 net.sf.ehcache.CacheManger 转换为 org.springframework.cache.CacheManager?