java - 如何修复此正则表达式(匹配字典条目)

标签 java regex parsing

我正在使用一本西类牙语词典,其定义如下:

l. a. c. Buitre, alimoche. adj. Persona alelada. (Cornago). GOICOECHEA. // 2. f. Persona torpe, despistada e irreflexiva. // 3. Estar mirando a los abantos. fr. fig. Ser despistado, soñador, no apercibirse de la realidad. Autol. RUIZ. // 4. f. esto es una prueba

适用以下规则:

  • 每个定义可以包含以下类别中的一个(且不得超过一个):
    • l。 A。 c.
    • f.
    • 米。
  • 类别始终位于定义的开头
  • 第一个定义从头开始,如果有更多定义,则以 \\n 开头。 其中“n”是一个数字(可以多于一位数字)

对于我给出的示例,应解析以下定义:

  1. (类别:l.a.c.)Buitre,alimoche。形容词人物阿雷拉达。 (科纳戈)。 GOICOECHEA
  2. (类别:f.)Persona torpe,despistada e irreflexiva。
  3. (无类别)Estar mirando a los abantos。神父。如图。 Ser despistado, soñador, no apercibirse de la realidad。奥托尔。鲁伊兹。
  4. (类别:f.)esto es una prueba

我正在尝试创建一个正则表达式来捕获每个定义(即 0 或 1 个类别+含义)。这就是我所拥有的

(?:(m\.|l\. a\. c\.|f\.) )?(.*?) (?:$|(?:\/\/ \d+. (?:(m\.|l\. a\. c\.|f\.) )?(.*?))+)

我正在测试它here我是这样写的:

(?:
    (m\.|l\. a\. c\.|f\.)  <-- First: unnamed group containing the named group 
                                      for the category  and one space
)?
(.*?)                      <-- Named group for the meaning
(?:                        <-- Unnamed group for end of line OR another definition
   $                       <--- (end of line)
   |                       <--- (OR)
   (?:\/\/ \d+.            <--- (Definition separator & number)
       (?:(m\.|l\. a\. c\.|f\.) )?(.*?) <-- Another definition
   )+                                   <-- There may be more than one definition, so we add '+'
)

我有几个问题:

  • 我不知道为什么它不起作用。看起来最后一个捕获组 (.*?) 直到下一个 \\ 才会扩展。我该如何修复它?
  • (m\.|l\.a\.c\.|f\.)应该更大(有更多类别)如何避免重复?
  • 我提供的正则表达式字符串中有一些重复,如何避免这种情况?

这是我的第一个重要的正则表达式示例,因此欢迎任何有关样式或总体改进的其他评论。

我的主要问题是为什么我的正则表达式不起作用。(这只是为了澄清......)

最佳答案

问题在于最后一个捕获组是非贪婪的。

(?:
    (m\.|l\. a\. c\.|f\.)
)?
(.*?)
(?:
   $
   |
   (?:\/\/ \d+.
       (?:(m\.|l\. a\. c\.|f\.) )?
       (.*?) <-- this is non-greedy.
   )
)+

因此,它将简单地匹配空字符串。模式末尾的 + 不会执行任何操作,因为它已经匹配过一次,这足以停止。

修复方法很简单:强制模式匹配整行。只需在末尾添加 $ 即可。

(?:(m\.|l\. a\. c\.|f\.) )?(.*?) (?:$|(?:\/\/ \d+. (?:(m\.|l\. a\. c\.|f\.) )?(.*?)))+$
<小时/>

编辑:使用单个正则表达式捕获每个类别和定义是不可能的。如果您使用单个模式来匹配整个字符串,则每个捕获组将仅包含它匹配的最后一个文本,因此您只能解析最后一个定义。

您可以使用此模式来匹配单个定义。

(?:^| \/\/ \d\. )(?:(?P<category>m\.|l\. a\. c\.|f\.) )?(?P<definition>.*?)(?:$|(?= \/\/ \d\.))

将其应用于字符串,直到不再找到匹配项以捕获所有定义。

while (matcher.find()){
   ... do something
}

Demo.

<小时/>

该模式的详细解释:

(?:
    ^ // match start of string
| // OR
     \/\/ \d\. // "\\ " literally, followed by a digit, a dot, and a space
)
(?:
    (?P<category> // in the named group "category", capture...
        m\.|l\. a\. c\.|f\. // one of "m.", "l. a. c.", "f."
    )  // and a space
)? // ...if possible.
(?P<definition> // in the named group "definition", capture...
    .*? // everything up to...
)
(?:
    $ // the end of the string
| // OR
    (?= // the start of the next definition. This needs to be enclosed in a lookahead assertion so as not to consume it.
         \/\/ \d\.
    ) 
)

关于java - 如何修复此正则表达式(匹配字典条目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27381333/

相关文章:

java - Eclipse : Failed to connect to remote VM. 连接被拒绝。

JavaScript 验证问题

java - 使用正则表达式将句子拆分为单词,其中单词还包含多个空格

python - 在线读取 csv 时出现错误 Error tokenizing data

使用 EntityManager 的 persist() 函数时出现 java.lang.NullPointerException (Spring 4 ORM)

java - 何时将jar放入ear根以及何时将它们放入lib文件夹

java - 限制300字的正则表达式

python - 使用 Python 查找文件大小的字符串中数组字符串的频率

linux - 如何使用爬虫解析文档

.net - 你如何在 vb.net 中解析 HTML