正则表达式帮助-如果字符在引号中则忽略它

正则表达式帮助-如果字符在引号中则忽略它

我们在工作中有一个基于 Web 的应用程序,您可以在其中的搜索框中输入正则表达式,它会从数据库中返回匹配结果

以下是数据库条目的示例。它们以逗号分隔(将每条记录视为一个家族 - 每个家族可以有 1 到 n 个条目):

record1: "john doe"<[email protected]>;male,"jane doe"<[email protected];female
record2: "john smith"<[email protected]>
record3: "smith, jane"<[email protected]>

我需要做的是输入一个正则表达式,这样我只能得到第一个条目。在实际情况下,输出将是分隔符之前的所有内容:

record1: "john doe"<[email protected]>;male
record2: "john smith"<[email protected]>
record3: "smith, jane"<[email protected]>

实际上,我所有的尝试都将“smith,jane”中的逗号视为分隔符。

如果逗号在引号中,我该如何忽略它?(为了将来的保障,忽略单引号中的逗号的能力也很好)

我可以仅有的使用正则表达式,而不是 awk/sed 等,并且正则表达式的风格是 POSIX 扩展。

答案1

亮点:你需要像评论指出的那样更详细地描述您的环境。

这里是我在 Unix shell 上的一次尝试sed
,是的,我知道你不想要sed,但它可能会帮助你在你的环境中构建正则表达式。

data.txt: 
"john doe"<[email protected]>;male,"jane doe"<[email protected];female
john_doe"<[email protected]>;male,"jane doe"<[email protected];female

# sed -n 's|^\("[^"]\+"[^,]\+\).*|\1| p' data.txt 
"john doe"<[email protected]>;male

此处的正则表达式思路是跳过第一对双引号,然后查找逗号。
如果没有双引号,则失败。
可以将其扩展为使用单引号。

更新
查找@后跟,...

data.txt: 
"john doe"<[email protected]>;male,"jane doe"<[email protected];female
john_doe"<[email protected]>;male,"jane doe"<[email protected];female

# sed -n 's|\([^@]\+[^,]\+\),.*|\1| p' data.txt 
"john doe"<[email protected]>;male
john_doe<[email protected]>;male

现在,您得到了两种情况,然后还有那些没有字符串名称甚至<>换行的情况。
但是,您的问题是依赖于record2 和 record3 的 -- 中断,其中您只有一封电子邮件并且没有逗号。如果您在每条记录的末尾,强制使用 a,则仍然有效。,

答案2

你不能用正则表达式可靠地做到这一点。您能做的最好的事情就是基于一堆假设进行丑陋的破解,如果您敢将这样的代码投入生产,这些假设最终肯定会被打破。(如果您不能使用全副武装且可操作的 Perl 正则表达式引擎的火力来做到这一点,那么您肯定不能使用 POSIX 扩展正则表达式来做到这一点。)

简而言之,为了可靠地解决这个问题,您将需要找到某种方法来扩展您正在使用的代码,以便它可以使用 CSV 解析库,或者如果失败,您将需要编写一个解析器。

当然,如果您无法修改处理相关文件的代码,那么您就只能陷入丑陋的黑客攻击中,在这种情况下,这是不幸的,因为我看不到任何真正可靠的方法可以使用 POSIX 正则表达式作为唯一的工具来产生所需的结果。

答案3

试图忽略引号内的逗号是有问题的,因为您想要查找的逗号也是“在引号中”(的结束引号"john doe"和的开始引号"jane doe")。除非您假设第一个引号存在,否则您将很难做出这种区分。

尝试一下这个:

^[^<]+<[^>]*>[^,\s]*

我假设每条记录都会有一个<email>,并且电子邮件后面的任何逗号都表示一条新记录。这只是用一个假设来换取另一个假设,但它在我的测试中有效。

答案4

使用正则表达式将引号外部的 , 分隔符更改为其他内容,例如制表符:

模式 ((?:[^,"]|"[^"]*")+),
替换 \1\t

然后按新的分隔符拆分

相关内容