gpt4 book ai didi

java - 如何管道/链接正则表达式

转载 作者:行者123 更新时间:2023-11-30 03:03:23 26 4
gpt4 key购买 nike

我必须从字符串文本中提取度量单位和数量。就像这个示例一样:

Original String // result:

abc1mgabc // extract 1 and mg separately
abc100mlabc //100 and ml
abc256kgabc //256 and kg

到目前为止,我首先使用这个正则表达式:

(?i)\d{1,5}(mg|g|gr|kg|ml|l)

提取数量和单位并将其存储到quant_unit字符串中。

之后,我应用了 quant_unit 这两个正则表达式:\d(?i)(mg|g|gr|kg|ml| l)分别提取“数量”和“计量单位”。

但我认为它必须有一种方法可以通过在原始字符串上应用正则表达式(对于每个要提取的项目)来单独提取它?

我虽然使用了类似的东西:

original_string -> applyRegex(提取度量和单位)-> applyRegex2(从中提取度量或单位)。

使用自己的正则表达式或 Java 中的 Pattern 类。

我创建了一个枚举来轻松访问模式:

public enum Patterns {

//the expression is: (?i)\d{1,5}(mg|g|gr|kg|ml|l)
QUANTITY_UNIT("(?i)\\d{1,5}(" + MeasureUnit.getRegex() + ")"),
QUANTITY("\\d"),
UNIT("(?i)(" + MeasureUnit.getRegex() + ")");

private Pattern pattern;

Patterns(String patternString) {
System.out.println(patternString);
pattern = pattern.compile(patternString);
}

public Pattern getPattern() {
return pattern;
}

public Matcher getMatcher(CharSequence input) {
return getPattern().matcher(input);
}

public String findGroup(CharSequence input) {
Matcher matcher = getMatcher(input);
matcher.find();
return matcher.group();

}

以及所需行为的单元测试:

public class PatternsTest {

@Test
public void quantityUnit() {
String testString = "abc1kgabc1l";
String fg = Patterns.QUANTITY_UNIT.findGroup(testString);
Assert.assertEquals("1KG", fg);
}


@Test
public void quantity() {
String testString = "abc1kgabc1l";
String fg = Patterns.QUANTITY.findGroup(testString);
Assert.assertEquals("1", fg);
}


@Test
public void unity() {
String testString = "abc1kgabc1l";
String fg = Patterns.UNIT.findGroup(testString);
Assert.assertEquals("kg", fg);
}

}
<小时/>

编辑

我根据评论和答案进行了一些重构,现在工作正常:

public enum Patterns {

QUANTITY_UNIT("(?i)([0-9]+)(" + MeasureUnit.getRegex() + ")");

private Pattern pattern;

Patterns(String patternString) {
pattern = pattern.compile(patternString);
}

public Pattern getPattern() {
return pattern;
}

public Matcher getMatcher(CharSequence input) {
return getPattern().matcher(input);
}

public String getQuantity(CharSequence input) {
final int group_idx = 1;

Matcher matcher = getMatcher(input);
boolean found = matcher.find();
return found ? toLower(matcher.group(group_idx)) : "";
}

private String toLower(String input) {
return input.toLowerCase();
}

public String getUnity(CharSequence input) {
final int group_idx = 2;

Matcher matcher = getMatcher(input);
boolean found = matcher.find();
return found ? toLower(matcher.group(group_idx)) : "";
}
}
<小时/>

测试:

public class MeasureUnityTest {


@Test
public void quantity() {
String testString = "abc1kgabc1l";
String fg = QUANTITY_UNIT.getQuantity(testString);
Assert.assertEquals("1", fg);
}


@Test
public void unity() {
String testString = "abc1kgabc1l";
String fg = QUANTITY_UNIT.getUnity(testString);
Assert.assertEquals("kg", fg);
}

@Test
public void unityUpperCase() {
String testString = "abc1KGabc1l";
String fg = QUANTITY_UNIT.getUnity(testString);
Assert.assertEquals("kg", fg);
}


@Test
public void unityNoOccurrence() {
String testString = "fasfasfasfaf";
String fg = QUANTITY_UNIT.getQuantity(testString);
Assert.assertEquals("", fg);
}

@Test
public void unityEmptyString() {
String testString = "";
String fg = QUANTITY_UNIT.getQuantity(testString);
Assert.assertEquals("", fg);
}

/* If more than one matches, return the first*/
@Test
public void unityMoreThanOne() {
String testString = "abc5mlabc5kg";
String fg = QUANTITY_UNIT.getUnity(testString);
Assert.assertEquals("ml", fg);
}

/* If more than one matches, return the first*/
@Test
public void quantityMoreThanOne() {
String testString = "abcm5mlabc1kg";
String fg = QUANTITY_UNIT.getQuantity(testString);
Assert.assertEquals("5", fg);
}

}

最佳答案

概括所有评论,您可以使用与此类似的内容 ( IDEONE link ):

String[] tests = { "abc1mgabc","abc100mlabc","abc256kgabc"};
Pattern ptrn = Pattern.compile("(?i)([0-9]+)(gr|kg|mg|ml|g|l)");
for (String s: tests) {
Matcher matcher = ptrn.matcher(s);
while (matcher.find()) {
System.out.println("QNTY: " + matcher.group(1));
System.out.println("UNIT:" + matcher.group(2));
}
}

输出:

QNTY: 1
UNIT:mg
QNTY: 100
UNIT:ml
QNTY: 256
UNIT:kg

参见IDEONE demo

要点:

  • 您可以只使用 2 个捕获组并使用 1 个正则表达式捕获两个实体。
  • 确保最长的替代项在交替中排在第一位,因为在 Java 正则表达式中选择了找到的第一个替代项(这不符合选择找到的最长替代项的 POSIX 标准)。
  • 如果您不确定数字有多大,使用 + 量词(一次或多次出现)就足够了,而不是限制 {1,5} 只会匹配 1 到 5 次出现。

关于java - 如何管道/链接正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35398496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com