【问题标题】:Regex - repeating 2 letters on by one正则表达式 - 一个重复 2 个字母
【发布时间】:2021-03-13 01:52:14
【问题描述】:

我有一个使用某种逻辑生成一些单词的代码,并且我有正则表达式 1(向下看)。但是我需要生成正确的单词,例如单词 1。我的逻辑包括我提到的数学模式。我需要正确的模式来生成单词,例如单词 1 而不是 2。该模式的逻辑是:

  1. 单词以大写元音或辅音开头
  2. 长度为 2 个或更多符号(整个单词)
  3. 连续的元音或辅音不得超过两个
Aakemenkyu
Klepathass
Waknampite
Flaetobsak
Oladkinqyt
Mmalinnetj

这些是单词 1

[A-Z](([aeiouy]|[bcdfghjklmnpqrstvwxz]){1,2})*

这是正则表达式 1

这个正则表达式不起作用,我的代码逻辑会生成下一个单词:

Ijythlzuoe
Tervkpxyib
Ifuemkoeui
Mqjtobojex
Ephyrjiuau

这些是单词 2

例如,在单词Ijythlzuoe中有thl(辅音连续重复3次)和uoe(元音重复)

请帮忙。

【问题讨论】:

  • 什么语言的正则表达式?
  • 我不太明白你的最后一段,但你的正则表达式似乎与你所有的例子相匹配。您希望它匹配哪些示例,不希望它匹配哪些示例?
  • @xdhmoore 我认为操作正在尝试使用给定的正则表达式(逆向工程)生成字符串。
  • @ansvir,你能澄清一下吗?帖子以“我需要正则表达式......”开头,所以我只是猜测“生成”这个词真的是为了说“匹配”......
  • @xdhmoore,语言是java

标签: java regex


【解决方案1】:

我认为“生成”实际上是指“匹配”。

您可以使用此正则表达式验证 1-2 个辅音后跟 1-2 个元音,反之亦然:

/^(([aeiouy]){1,2})?(([bcdfghjklmnpqrstvwxz]){1,2}([aeiouy]){1,2})*(([bcdfghjklmnpqrstvwxz]){1,2})?$/i

使用 JavaScript 的测试用例,但这个正则表达式应该适用于任何语言:

const regex = /^(([aeiouy]){1,2})?(([bcdfghjklmnpqrstvwxz]){1,2}([aeiouy]){1,2})*(([bcdfghjklmnpqrstvwxz]){1,2})?$/i;
[
  'Aakemenkyu',
  'Klepathass',
  'Waknampite',
  'Flaetobsak',
  'Oladkinqyt',
  'Mmalinnetj',
  'Ijythlzuoe',
  'Tervkpxyib',
  'Ifuemkoeui',
  'Mqjtobojex',
  'Ephyrjiuau'
].forEach(str => {
  console.log(str + ' => ' + regex.test(str));
});

输出:

Aakemenkyu => true
Klepathass => true
Waknampite => true
Flaetobsak => true
Oladkinqyt => true
Mmalinnetj => true
Ijythlzuoe => false
Tervkpxyib => false
Ifuemkoeui => false
Mqjtobojex => false
Ephyrjiuau => false

解释:

  • ^ - 锚点在字符串的开头
  • ( - 第 1 组的开始(可以设为非捕获组 (?:...)
    • ([aeiouy]){1,2} - 一到两个元音
  • )? - 第 1 组结束,? 使其可选
  • ( - 第 2 组开始
    • ([bcdfghjklmnpqrstvwxz]){1,2} - 一到两个辅音
    • ([aeiouy]){1,2} - 一到两个元音
  • )* - 第 2 组结束,零到多次重复
  • ( - 第 3 组开始
    • ([bcdfghjklmnpqrstvwxz]){1,2} - 一到两个辅音
  • )? - 第 3 组结束,? 使其可选
  • $ - 锚点在字符串的末尾
  • 使用i 标志忽略大小写

【讨论】:

  • @Toto:“辅音和元音不应重复超过 2 次”,这就是这个正则表达式的作用,JvdV 的答案也是如此。令人困惑的部分是 OP 在元音列表中包含 y
  • @Toto:对不起,我不明白。当我阅读 OP 的问题时,aabbaacc 应该匹配。
  • 不错的答案。 @Toto 可能意味着所有输入都以大写字母开头,这就是为什么“aabbaacc”不应该匹配?
  • 在 OP 澄清后,看来您是对的(并获得我的投票!)。
  • @Thefourthbird:是的,这是正确的。但是,OP 使用模式生成的那一部分,因此不会有空字符串。然而,我的正则表达式忽略了大小写,在 OP 澄清后,事实证明它应该是首字母大写,后跟小写字母。我没有在正则表达式中添加积极的前瞻和忽略大小写切换,因为正则表达式引擎是未知的。
【解决方案2】:

你可以试试:

^(?=[A-Z][a-z]*$)(?i)(?!.*[aeiouy]{3}|.*[^aeiouy\n]{3})[a-z]+$

在线查看demo

  • ^ - 开始字符串锚点。
  • (?=[A-Z][a-z]*$) - 正向前瞻,以大写字母开头的字符串,而其余部分为小写直到结尾。
  • (?i) - 内联修饰符匹配余数不区分大小写。
  • (?! - 打开负前瞻:
    • .*[aeiouy]{3} - 最多匹配类中任意三个连续字符。
    • | - 或者:
    • .*[^aeiouy\n]{3} - 最多匹配任意三个不在类中的连续字符。
    • ) - 关闭负前瞻。
  • [a-z]+ - a-z 中的 1+ 个字符(不区分大小写)。
  • $ - 结束字符串锚。

【讨论】:

  • 我认为应该是^(?=[A-Z][a-z]+$) 来匹配至少2个字符)
【解决方案3】:

正则表达式(?=[A-Z][A-Za-z])(?i)(?!.*[aeiouy]{3}|.*[^aeiouy]{3})[a-z]+ 应该满足您的要求。

来自regex101的正则表达式解释:

演示:

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream.of("Aakemenkyu",
                  "Klepathass",
                  "Waknampite",
                  "Flaetobsak",
                  "Oladkinqyt",
                  "Mmalinnetj",
                  "Ijythlzuoe",
                  "Tervkpxyib",
                  "Ifuemkoeui",
                  "Mqjtobojex",
                  "Ephyrjiuau").forEach( s -> {
                      System.out.println(s + " => " + s.matches("(?=[A-Z][A-Za-z])(?i)(?!.*[aeiouy]{3}|.*[^aeiouy]{3})[a-z]+"));
                  });
    }
}

输出:

Aakemenkyu => true
Klepathass => true
Waknampite => true
Flaetobsak => true
Oladkinqyt => true
Mmalinnetj => true
Ijythlzuoe => false
Tervkpxyib => false
Ifuemkoeui => false
Mqjtobojex => false
Ephyrjiuau => false

【讨论】:

猜你喜欢
  • 2014-09-10
  • 2023-03-30
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2018-10-18
  • 1970-01-01
  • 2022-06-27
相关资源
最近更新 更多