我有一个像这样的字符串/列
String a = "000003023_AggregateStopLossLimit_W x3A 973911_2012-12-22.PDF";
我想创建一个子字符串,其中没有' x3A 973911'
部分。
这意味着我想要这样的东西,
000003023_AggregateStopLossLimit_W_2012-12-22.PDF
有一个这样的字符串列表,它们具有不同的值,但格式相同。我希望删除字符串的一部分,它在第一个空格之后,在下一个'_'结束。
这就是我已经做过的,这很好用,但想知道是否有更好的方法。
String b = a.replaceAll(a.substring(a.indexOf(" "), a.indexOf("_",a.indexOf(" "))),"");
如果我可以在db本身(即oracle,而不是java)中执行此操作,那会更好。有没有想过直接使用select?
从列中获取这个格式化的字符串还有一个要求,我不想显示文件的扩展名。在“。”之后没什么。应该显示,这意味着像'000003023_AggregateStopLossLimit_W_2012-12-22'
这样的事情
我使用之前的APC解决方案尝试了以下内容
select regexp_replace ( your_string
, '([^[:space]]*) (.*)_(.*)....'
, '\1_\3') as new_string from your_table
现在工作正常。
这应该删除最后4个字符,并且如果扩展名大于或小于3或者字符串没有被截断,则存在无法获得正确结果的风险。我正在寻找一种更美观的方式来做到这一点
有机会吗?
答案 0 :(得分:4)
final String r = a.replaceAll(" .*?(?=_)", "");
如果你打印r,它会输出:
000003023_AggregateStopLossLimit_W_2012-12-22.PDF
答案 1 :(得分:3)
在数据库中执行此操作:
select regexp_replace ( your_string
, '([^[:space]]*) (.*)_(.*)'
, '\1_\3') as new_string
from your_table
不幸的是,Oracle在其正则表达式实现中没有任何强制执行惰性(非贪婪)的语法。这就是为什么我的原始'(。*)'包括x3A
:它与最后一个空格匹配,后面跟着下划线。但是,否定语法会将字符串隔离到第一个空格。
“W失踪后的'_'。还有机会得到它吗?”
您可以随意格式化替换字符串。简单的方法是做我已经完成的工作,并在两个匹配的模式之间硬编码下划线。或者你可以把它作为一个搜索模式,并将它包含在替换字符串中(尽管你更喜欢用它来做更复杂的搜索)。
Oracle在10g中引入了正则表达式;功能涵盖in the documentation。正则表达式实现符合POSIX标准,因此它缺少Perl中可能遇到的一些功能。正则表达式支持在an appendix to the SQL ref.
中有详细说明至于教程,我有一本很复杂的O'Reilly口袋书;我在Open World 2003获得了我的副本,但电子书的价格合理。 Buy it here。 Anotgher的良好起点是OTN论坛上cd
的一系列主题:start reading here。
答案 2 :(得分:2)
如果您需要SQL解决方案,这将更新行:
update yourtable
set field = substr(field, 0, instr(field, ' ')-1) || substr(field, instr(field, '_', instr(field, ' ')))
;
这将只显示转换后的值:
select
yourtable.field,
case
when instr(field, '_', instr(field, ' '))>instr(field, ' ')
then substr(field, 0, instr(field, ' ')-1) || substr(field, instr(field, '_', instr(field, ' ')))
else field
end as new_field
from
yourtable
答案 3 :(得分:1)
replaceAll
将正则表达式作为参数,如果子字符串包含正则表达式标记(例如[
,+
),则会出现意外行为。
您可以使用replace
来代替相同的东西但是将字符串作为参数。
除此之外,如果你知道你将有一个空格和_
作为分隔符,并且其间的子字符串不会出现在其他地方,那么你的方法看起来很好。您可以使用中间变量使其更具可读性:
int start = a.indexOf(" ");
int end = a.indexOf("_", start);
String b = a.substring(0, start) + a.substring(end, a.length());
答案 4 :(得分:1)
除了您提供的代码中的正则表达式问题,我发现它也不太可读。
请尝试以下操作:
int f = a.indexOf(" ");
int l = a.lastIndexOf("_");
a = a.substring(0,f+1) + a.substring(l+1, a.length);
答案 5 :(得分:1)
您应该替换REGEX_REPLACE函数。
http://docs.oracle.com/cd/B12037_01/server.101/b10759/functions115.htm#SQLRF06302
答案 6 :(得分:0)
@Kent上面提供的Java解决方案非常优雅,我推荐它。也就是说,如果您想使用Oracle的正则表达式引擎来完成此任务,您可以尝试以下方法:
WITH t1 AS (
SELECT '000003023_AggregateStopLossLimit_W x3A 973911_2012-12-22.PDF' AS filename
FROM dual
)
SELECT filename, REGEXP_REPLACE(filename, ' [^_]*', '')
FROM t1