我正在使用X12 EDI文件(特别是835s用于医疗保健中的那些人),我有一个特定的供应商正在使用非HIPAA兼容版本(我认为是3090)。问题在于,在特定的细分市场(PLB-再次,对于那些关心的人),他们发送的代码不再受HIPAA标准的支持。我需要找到特定代码,并使用更正后的代码进行更新。
我认为一个正则表达式最适合这个,但我仍然是Regex的新手,我不知道从哪里开始。我目前的方法是将文件转换为字符串数组,找到以“PLB”开头的数组,将其分解为字符串数组,查找代码并更改它。正如你猜测的那样,那些应该(我认为)相当简单的代码非常详细。
以下是我正在寻找的样本:
~PLB|1902841224|20100228|49>KC15X078001104|.08~
以下是我要将其更改为:
~PLB|1902841224|20100228|CS>KC15X078001104|.08~
有什么建议吗?
更新:经过审核,我发现我的问题还不够完善。上面的记录是一个例子,但它不一定是一个特定的格式匹配 - 这个记录和其他一些(在另一个文件中)我必须修复的事情之间有三件事可能会发生变化。他们是:
我的计划是将String.Format()与我的Regex匹配字符串一起使用,以便|和>可以用正确的字符替换。
并记录在案。是的,我讨厌ANSI X12。
答案 0 :(得分:2)
假设“违规”代码始终为49
,您可以使用以下内容:
resultString = Regex.Replace(subjectString, @"(?<=~PLB|\d{10}|\d{8}|)49(?=>\w+|)", "CS");
如果它是49
分隔符之后的第一个元素,前面是一组8位数,另一个|
,一组10位数,另一个|
,则查找|
~PLB
1}}和>
。它还会查看后跟|
,然后是任意数量的字母数字字符,还有一个resultString = Regex.Replace(subjectString, @"(?<=~PLB\1\w+\1\d{8}(\W))49(?=\W\w+\1)", "CS");
。
根据新的要求(以及.NET是少数允许在lookbehind中重复重复的正则表达式之一的幸运巧合),您可以将其更改为:
|
现在允许任何非字母数字字符作为分隔符而不是>
或|
(但在{{1}}的情况下,它必须始终是相同的),并且限制关于第一个字段的字符数已经松动。
答案 1 :(得分:1)
另一种类似的方法适用于任何有效的X12文件,以便在匹配的段上用另一个数据值替换单个数据值:
public void ReplaceData(string filePath, string segmentName,
int elementPosition, int componentPosition,
string oldData, string newData)
{
string text = File.ReadAllText(filePath);
Match match = Regex.Match(text,
@"^ISA(?<e>.).{100}(?<c>.)(?<s>.)(\w+.*?\k<s>)*IEA\k<e>\d*\k<e>\d*\k<s>$");
if (!match.Success)
throw new InvalidOperationException("Not an X12 file");
char elementSeparator = match.Groups["e"].Value[0];
char componentSeparator = match.Groups["c"].Value[0];
char segmentTerminator = match.Groups["s"].Value[0];
var segments = text
.Split(segmentTerminator)
.Select(s => s.Split(elementSeparator)
.Select(e => e.Split(componentSeparator)).ToArray())
.ToArray();
foreach (var segment in segments.Where(s => s[0][0] == segmentName &&
s.Count() > elementPosition &&
s[elementPosition].Count() > componentPosition &&
s[elementPosition][componentPosition] == oldData))
{
segment[elementPosition][componentPosition] = newData;
}
File.WriteAllText(filePath,
string.Join(segmentTerminator.ToString(), segments
.Select(e => string.Join(elementSeparator.ToString(),
e.Select(c => string.Join(componentSeparator.ToString(), c))
.ToArray()))
.ToArray()));
}
使用的正则表达式验证了正确的X12交换包络,并确保文件中的所有段至少包含一个字符名称元素。它还解析了元素和组件分隔符以及段终止符。
答案 2 :(得分:0)
假设您的代码始终是管道字符|
之后和大于号>
之前的两位数字,您可以这样做:
var result = Regex.Replace(yourString, @"(\|)(\d{2})(>)", @"$1CS$3");
答案 3 :(得分:0)
你可以用正则表达式来分解它。 如果我正确理解你的例子中的| 2之间的2个字符并且&gt;需要是字母而不是数字。
~PLB\|\d{10}\|\d{8}\|(\d{2})>\w{14}\|\.\d{2}~
此模式将与旧模式匹配并捕获|之间的字符和&gt;。然后您可以使用它来修改(在数据库或其他内容中查找)并使用以下模式进行替换:
(?<=|)\d{2}(?=>)
答案 4 :(得分:0)
这将寻找~PLB |#|#|在开始时并在&gt;之前替换2个数字。与CS。
Regex.Replace(testString, @"(?<=~PLB|[0-9]{10}|[0-9]{8})(\|)([0-9]{2})(>)", @"$1CS$3")
答案 5 :(得分:0)
X12协议标准允许在标题中指定元素和组件分隔符,所以任何硬编码“|”的东西和“&gt;”人物最终可能会破裂。由于标准要求用作分隔符的字符(和段终止符,例如“〜”)不能出现在数据中(没有转义序列允许它们被嵌入),因此解析语法非常简单。也许你已经在做类似的事了,但为了便于阅读......
// The original segment string (without segment terminator):
string segment = "PLB|1902841224|20100228|49>KC15X078001104|.08";
// Parse the segment into elements, then the fourth element
// into components (bounds checking is omitted for brevity):
var elements = segment.Split('|');
var components = elements[3].Split('>');
// If the first component is the bad value, replace it with
// the correct value (again, not checking bounds):
if (components[0] == "49")
components[0] = "CS";
// Reassemble the segment by joining the components into
// the fourth element, then the elements back into the
// segment string:
elements[3] = string.Join(">", components);
segment = string.Join("|", elements);
显然比单个正则表达式更冗长,但解析X12文件就像在单个字符上拆分字符串一样简单。除了固定长度标题(定义分隔符)之外,可以使用Split解析整个事务集:
// Starting with a string that contains the entire 835 transaction set:
var segments = transactionSet.Split('~');
var segmentElements = segments.Select(s => s.Split('|')).ToArray();
// segmentElements contains an array of element arrays,
// each composite element can be split further into components as shown earlier
答案 6 :(得分:0)
我发现的工作如下:
parts = original.Split(record);
for(int i = parts.Length -1; i >= 0; i--)
{
string s = parts[i];
string nString =String.Empty;
if (s.StartsWith("PLB"))
{
string[] elems = s.Split(elem);
if (elems[3].Contains("49" + subelem.ToString()))
{
string regex = string.Format(@"(\{0})49({1})", elem, subelem);
nString = Regex.Replace(s, regex, @"$1CS$2");
}
我仍然需要将原始文件拆分成一组字符串,然后评估每个字符串,但接缝现在正在工作。
如果有人知道如何绕过那个字符串。在顶部分开,我很乐意看到一个样本。