首页 > 解决方案 > 正则表达式匹配字符串中间的子字符串

问题描述

我需要帮助完成正则表达式。我有以下正则表达式: /(?i)encntr(?-i)/gi

https://regex101.com/r/t4pUkr/1/

我有以下三个文件名:

我上面的正则表达式匹配所有 3 个,但我只希望它匹配第一个要点。所以我试图使用 ^(not) 运算符来实现这一点,但我没有得到任何地方。忽略上一句,我对使用 ^ 的理解是不明智的。此外,如果我可以在不依赖 - 和 . encntr、encntrprov 和 encntrlocation 都包含在其中。我不创作这些文件,也不能保证作者遵循命名约定。因此我不能保证 - 和 . 将永远在那里。

可能的其他文件名示例:

使用这个正则表达式的目的是从我的代码中删除内部 if 语句。我正在遍历枚举值并检查传入文件名中是否存在枚举值。

现在代码使用 txtFilename.Contains(possibleIdentifierLower, StringComparison.OrdinalIgnoreCase)) 查看传入的文件名是否包含枚举值之一。但是在枚举 encntr 的情况下,对于 encntr、encntrprov 和 encntrlocation 文件名,Contains 方法返回 true。所以我必须做一个额外的检查来确定它是哪一个。我想通过在正则表达式中提供这些值来利用正则表达式仅匹配 encntr、encntrprov 或 encntrlocation。因此 encntr 无法与使用正则表达式的 encntrprov 或 encntrlocation 匹配。

这是我要更新的代码片段。

public static FilenameIdentifierEnum IdentifyFile(string txtFilename)
{
    FilenameIdentifierEnum identifier = FilenameIdentifierEnum.unassigned;

    foreach (FilenameIdentifierEnum possibleIdentifier in Enum.GetValues(typeof(FilenameIdentifierEnum)))
    {
        // I would like this Regex.Match to eliminate the need to have the inner if statements 
        //if(Regex.IsMatch(txtFilename, $"(?i){possibleIdentifier.ToString()}(?-i)", RegexOptions.IgnoreCase))
        if (txtFilename.Contains(possibleIdentifierLower, StringComparison.OrdinalIgnoreCase))
        {
            identifier = possibleIdentifier;

            if (identifier == FilenameIdentifierEnum.encntr)
                identifier = EncntrCaseChecking(txtFilename, identifier);
            if (identifier == FilenameIdentifierEnum.appt)
                identifier = ApptCaseChecking(txtFilename, identifier);

            break;
        }
    }

    if (identifier == FilenameIdentifierEnum.unassigned)
    {
        throw new UnknownFileException($"Unknown identifier in filename or no file identifier in filename found. Text Filename: {txtFilename}");
    }

    return identifier;
}

private static FilenameIdentifierEnum EncntrCaseChecking(string txtFilename, FilenameIdentifierEnum possibleIdentifier)
{
    possibleIdentifier = (txtFilename.Contains(FilenameIdentifierEnum.encntrloc.ToString(), StringComparison.OrdinalIgnoreCase)
        ? FilenameIdentifierEnum.encntrloc
        : possibleIdentifier);

    possibleIdentifier = (txtFilename.Contains(FilenameIdentifierEnum.encntrprov.ToString(), StringComparison.OrdinalIgnoreCase)
        ? FilenameIdentifierEnum.encntrprov
        : possibleIdentifier);

    return possibleIdentifier;
}

private static FilenameIdentifierEnum ApptCaseChecking(string txtFilenameLower, FilenameIdentifierEnum possibleIdentifier)
{
    return (txtFilenameLower.Contains(FilenameIdentifierEnum.apptpart.ToString(), StringComparison.OrdinalIgnoreCase)
         ? FilenameIdentifierEnum.apptpart
         : possibleIdentifier);
}

public enum FilenameIdentifierEnum
{
    unassigned,
    encntr,
    encntrprov,
    encntrloc,
    persondemo,
    personbenefitcoverage,
    personprov,
    medication,
    immunization,
    allergy,
    diagnosis,
    problem,
    labresults,
    socialhistory,
    vitals,
    procedures,
    appt,
    apptpart,
    appointments,
    appointmentparticipant,
    encounterlocation,
    result
}

谢谢您的帮助。

标签: c#regex

解决方案


使用这个正则表达式:

(encntr\..*?)

仅与子字符串匹配encntr.

请注意,^不是(非)运算符。 ^用于从字符串的开头进行匹配。


推荐阅读