获取没有正则表达式的子串

时间:2016-11-04 19:35:33

标签: string devexpress substring string-matching

这将是一个非常长的问题,所以请耐心等待(也请帮助我,因为我在我的机智结束时)但是让我告诉你我先做的事情。

我有一种压力,它是连接不同东西的结果(它最终是一个长串)。一个例子是:

C1;371 (Huz-fer)/GT(BLEA)56Mar<sup>nq5(LAG-HQRZ3*,-tMoline)KTA</sup> (iBet-huz/W-HEAPP) [stock 12345] [pregnant]

让我分解字符串的结构。

正式名称

C1;371 (Huz-fer)/GT(BLEA)56Mar<sup>nq5(LAG-HQRZ3*,-tMoline)KTA</sup>

这将始终位于字符串的开头,可能是一个长名称,也可能包含()中包含的字符串。

型号名称

(iBet-huz/W-HEAPP)

这是我需要获取和提取的内容 - 它将始终紧跟在正式名称之后,并始终包含在()中。 它还可能包含另一组()中包含的子字符串 - 因此(iBet-huz/W-(vuts)HEAPP)完全可能

库存

[stock 12345]

这将始终包含在[]中,并以stock开头。

动物类型

[pregnant]

这将始终位于[]中的字符串末尾。

  

在上面的示例中,我需要获取模型名称   (iBet-huz/W-HEAPP)或在另一个案例中提及   (iBet-huz/W-(vuts)HEAPP)。在Oracle SQL中,我可以很容易地做到这一点   使用正则表达式:

SELECT DISTINCT REGEXP_SUBSTR(ss.strain_value, '\(.*?\)', 1, REGEXP_COUNT(ss.strain_value, '\(.*?\)')) AS name
FROM species_strain ss
WHERE INSTR(ss.strain_value, '(', 1, 1) > 0
ORDER BY name ASC
     

但我现在的问题是我需要在第三方做同样的事情   剥离了我可以使用的可用功能的软件   Oracle(REGEXP_SUBSTRREGEXP_COUNT)是其中之一   这意味着我在查询时不能进行任何字符串操作   那个软件。幸运的是,他们在查询之外提供了一些工具   用于字符串操作(尽管不是很广泛)。

可用的字符串操作函数

  • Ascii(String) - 返回字符表达式中最左边字符的ASCII代码值。
  • Char(Number) - 将integerASCIICode转换为字符。
  • CharIndex(String1, String2) - 返回String2中String1的起始位置,从零字符位置开始到字符串结尾。
  • CharIndex(String1, String2, StartLocation) - 返回String2中String1的起始位置,从StartLocation字符位置开始到字符串结尾。
  • Concat(String1, ... , StringN) - 返回一个字符串值,其中包含当前字符串与任何其他字符串的串联。
  • Contains(String, SubString) - 如果SubString出现在String中,则返回True;否则,返回False。
  • EndsWith(String, EndString) - 如果String的结尾与EndString匹配,则返回True;否则,返回False。
  • Insert(String1, StartPosition, String2) - 在StartPositon指定的位置将String2插入String1。
  • Len(Value) - 返回一个整数,该整数包含字符串中的字符数或存储变量所需的标称字节数。
  • Lower(String) - 以小写形式返回String。
  • PadLeft(String, Length) - 左对齐已定义字符串中的字符,在其左侧填充空白字符,最大为指定的总长度。
  • PadLeft(String, Length, Char) - 左对齐已定义字符串中的字符,将其左侧的指定字符填充到指定的总长度。
  • PadRight(String, Length) - 右对齐已定义字符串中的字符,在其左侧填充空白字符,最大为指定的总长度。
  • PadRight(String, Length, Char) - 右对齐定义的字符串中的字符,将其左侧的指定字符填充到指定的总长度。
  • Remove(String, StartPosition, Length) - 从指定位置开始,从此实例中删除指定数量的字符。
  • Replace(String, SubString2, String3) - 返回String1的副本,其中SubString2已被String3替换。
  • Reverse(String) - 反转字符串中元素的顺序。
  • StartsWith(String, StartString) - 如果String的开头与StartString匹配,则返回True;否则,返回False。
  • Substring(String, StartPosition, Length) - 从String中检索子字符串。子字符串从StartPosition开始并具有指定的Length。
  • Substring(String, StartPosition) - 从String中检索子字符串。子字符串从StartPosition开始。
  • ToStr(Value) - 返回对象的字符串表示。
  • Trim(String) - 从String中删除所有前导和尾随SPACE字符。
  • Upper(String) - 以大写形式返回String。

通过上述可用功能,我能够为模型名称为(iBet-huz/W-HEAPP)的第一种情况提供解决方案,但不适用于模型为(iBet-huz/W-(vuts)HEAPP)的下一种情况。

MY CURRENT SOLUTION(不解决第二种情况)

在我们使用的第三方软件中,您可以创建变量并使用上面列举的函数。

--------------------------------------------------------------------------
[reversed_strain]
--------------------------------------------------------------------------
Trim(Reverse([STRAIN_VALUE]))

--------------------------------------------------------------------------
[removed_animal_type]
--------------------------------------------------------------------------
Iif(
    StartsWith([reversed_strain], ']'),
    Trim(Remove([reversed_strain], 0, CharIndex('[', [reversed_strain]) + 2)),
    [reversed_strain]
)

--------------------------------------------------------------------------
[model_name]
--------------------------------------------------------------------------
Iif(
    StartsWith([removed_animal_type], ')'),
    Trim(Reverse(Substring([removed_animal_type], 1, CharIndex('(', [removed_animal_type]) - 1))),
    [STRAIN_VALUE]
)

我的方法背后的基本理念:

  1. 反转整个字符串,将动物类型,股票和模型名称放在字符串的开头。
  2. 删除动物类型 - 将股票放在字符串的开头。
  3. 删除股票 - 将模型名称放在字符串的开头。
  4. 从开头到第一个(获取字符串 - 我之所以要查找左括号的原因是因为我颠倒了字符串。
  5. 您能否帮我修改我的解决方案,以便我还可以考虑第二种情况,即我可以在模型名称中包含任意数量的()

    我知道问题已经很久了,但如果您需要更多信息,请告诉我。

    附录

    我的解决方案并没有告诉我删除字符串的stock部分,但是那很好我可以做同样的事情去除动物类型所以不要这么做担心它 - 想象一下stock已被删除。

1 个答案:

答案 0 :(得分:1)

如果您的formal namemodel name按空格分隔,则可以使用它来查找model name
这是一个例子:

--------------------------------------------------------------------------
[strain_removed]
--------------------------------------------------------------------------
Substring([strain_value], 0, CharIndex(') [', [strain_value]) + 1)

--------------------------------------------------------------------------
[model_name]
--------------------------------------------------------------------------
Substring([strain_removed], Len([strain_removed]) - CharIndex('( ', Reverse([strain_removed])) - 1)

您可以尝试以下示例:

var table = new System.Data.DataTable();
table.Columns.Add("strain_value");

table.Rows.Add("C1;371 (Huz-fer)/GT(BLEA)56Mar<sup>nq5(LAG-HQRZ3*,-tMoline)KTA</sup> (iBet-huz/W-HEAPP) [stock 12345] [pregnant]");
table.Rows.Add("C1;371 (Huz-fer)/GT(BLEA)56Mar<sup>nq5(LAG-HQRZ3*,-tMoline)KTA</sup> (iBet-huz/W-(vuts)HEAPP) [stock 12345] [pregnant]");

var labelItem1 = new XRLabel();
labelItem1.DataBindings.Add("Text", null, "model_name");

var detail = new DetailBand();
detail.Controls.AddRange(new XRControl[] { labelItem1 });

var strain_removed = new CalculatedField();
strain_removed.Name = "strain_removed";
strain_removed.Expression = "Substring([strain_value], 0, CharIndex(') [', [strain_value]) + 1)";

var model_name = new CalculatedField();
model_name.Name = "model_name";
model_name.Expression = "Substring([strain_removed], Len([strain_removed]) - CharIndex('( ', Reverse([strain_removed])) - 1)";

var report = new XtraReport();
report.Bands.Add(detail);
report.DataSource = table;
report.CalculatedFields.AddRange(new[] { strain_removed, model_name });

report.ShowRibbonPreview();

但是在XtraReport中,您还可以使用脚本或事件在任何.net语言中执行任何操作。例如,您可以使用BeforePrint事件xrLabel控件和GetCurrentColumnValue方法获取当前列值:

using System.Text.RegularExpressions;

private void label1_BeforePrint(object sender, PrintEventArgs System.Drawing.Printing.PrintEventArgs e)
{
    string strain_value = GetCurrentColumnValue("strain_value").ToString();

    string model_name = ... // <= Your regex computations.

    label1.Text = model_name;
}