当字符串小于起始索引时,如何获得字符串中的字符索引?

时间:2014-10-07 14:19:24

标签: c# indexof substring

根据我的问题,我想获得当前起始索引之前的第一个逗号的索引。为了给出一个数据示例,我有一个这样的字符串:

Bob Green;PD,Andy Richards;BD,Frank Williams;OW,James Clack;PM

该字符串包含设置为[Persons Name];[Role]的元素,因此名称通过;(分号)与角色分隔,并且每个元素使用,彼此分隔(逗号)。

字符串中的元素可以是任何顺序,因此我的问题的原因是我希望获得角色OW的人名。我最初的想法是获得;OW,的索引并以某种方式从那里起作用。我显然可以从我的起始索引检查中向后循环字符串以查看该字符是否是逗号,但这似乎效率低下,那么有更好的方法来实现这一点吗?

修改

为了澄清,我只想获得与角色OW相关联的名称。这个角色应该只在字符串中出现一次。如果它没有,那么我很高兴只得到第一次出现,我认为IndexOf(&#34 ;; OW,")会这样做。我不需要其他角色或名称,只需要与OW相关联的名称。

此外,角色的长度只有2个字符。正如Matt Burland指出的那样,如果它在字符串的末尾,它就不会有一个尾随的逗号。但是,我可以修改我的indexof,只需搜索&#34 ;; OW"角色只有2个字符。

6 个答案:

答案 0 :(得分:4)

使用String.Split(',')将逗号上的字符串拆分为数组。然后创建一个自定义对象:

public RoledPerson{
    public string Person;
    public string Role;

    public RoledPerson(string input){
        string[] splitInput = input.Split(';');
        Person = splitInput[0];
        Role = splitInput[1];
    }
}

然后您可以将您的字符串转换为Enumerable,如下所示:

var RoledPersons inputstring.Split(',').Select(string => new RoledPerson(string));

然后你可以找到任何RoledPerson拥有OW作为他的角色:

var RoledPersonsWithRole = RoledPersons.Where(roledperson => roledperson.Role == "OW");

正如Matt Burland所说,你也可以用Dictionary<string, string>来做到这一点。我将留下如何解决这个问题。但是,这不支持具有相同名称的多个键,因此如果您多次使用相同的角色,这将不起作用。

免责声明:此处可能存在错误。

答案 1 :(得分:4)

正则表达式如何?这应该有效:

string role = "OW";
string str = "Bob Green;PD,Andy Richards;BD,Frank Williams;OW,James Clack;PM";
string pattern = "([^,]*);" + role;
var match = Regex.Match(str, pattern);
if (match.Success)
{
    Console.WriteLine(match.Groups[1].Value);
}

答案 2 :(得分:1)

使用包含起始位置的string.LastIndexOf重载:

string s = "Bob Green;PD,Andy Richards;BD,Frank Williams;OW,James Clack;PM";
int startRole = s.IndexOf(";OW");
int startName = s.LastIndexOf(',',startRole) + 1;  // start at the semicolon before the role
string name s.Substring(startName,(startRole-startName));

请注意,需要考虑边缘情况:

  • 所有角色都是两个角色(例如可能有OWX个角色吗?)
  • 如果OW角色是列表中的第一个,则
  • 之前将不会有逗号
  • 是否有多个OW个角色?如果是这样,您可以使用while循环,只需在上一个角色字符串的末尾开始搜索。

答案 3 :(得分:0)

这是获取所有OW不仅仅是第一个或最后一个的基本方法。将OW输入第二个函数。

class stringSections
{
    private List<string> role = new List<string>();
    private List<string> name = new List<string>();

    public void Input(string input)
    {
        string temp = "";
        for(int i =0;i<input.Length;i++)
        {
            if(input[i]==';')
            {
                name.Add(temp);
                temp = "";
            } else if(input[i]==',')
            {
                role.Add(temp);
                temp = "";
            } else
            {
                temp += input[i];
            }
        }
    }

    public List<string> GetAll(string prole)
    {
         List<string> reterners = new List<string>();

         for(int i = 0; i < role.Count;i++)
        {
            if (role[i] == prole)
            {
                reterners.Add(name[i]);
            }
        }
         return reterners;
    }
}

答案 4 :(得分:0)

处理@D Stanley提出的边缘案例:

    var s = "Bob Williams;OW,Bob Green;PD,Frank Williams;OW,Andy Richards;BD,James Clack;PM,Dave Williams;OW";
    var r = new Regex("(;OW,|^OW,|;OW$)");
    if (r.IsMatch(s)) 
    {
        foreach (Match m in r.Matches(s)) 
        {
            var rIdx = m.Index;
            var pIdx = s.LastIndexOf(",",rIdx);
            var person = s.Substring(pIdx + 1, rIdx - pIdx - 1);
            Console.WriteLine(person);
        }
    }
    else 
    {
        Console.WriteLine("Role not found");
    }

答案 5 :(得分:0)

确保我的解决方案&#39;我用以下代码编写了一个快速的apsx网页表单:

<asp:Content ID="Content3" ContentPlaceHolderID="PageContent" runat="server">
<asp:HiddenField ID="TestString" runat="server" Value="Bob Green;PD,Andy Richards;BD,Frank Williams;OW,James Clack;PM" />
<asp:Label ID="Label1" runat="server" Text="Find people in role"></asp:Label>
<asp:TextBox ID="RoleToFind" runat="server"></asp:TextBox><br /><br />
<asp:TextBox ID="Result" runat="server" Rows="10" TextMode="MultiLine" Width="294px"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" OnClick="SearchButton_Click" />

然后我按照Nate的回答

创建了一个班级
    [Serializable]
public class RolePerson
{
    public string Person { get; set; }
    public string Role { get; set; }
}

最后在aspx页面后面的代码中我添加了以下内容:

    public partial class teststack : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void SearchButton_Click(object sender, EventArgs e)
    {
        List<RolePerson> lrp = new List<RolePerson>();

        // Get the string from the hidden field
        string strData = this.TestString.Value;
        // split the string into an array each value in the array haveing name;role
        string[] strRecords = strData.Split(new Char[] {','});
        // process the array and add to the list
        foreach (string s in strRecords)
        {
            string[] strRecord = s.Split(new Char[] { ';' });
            lrp.Add(new RolePerson{
                Person = strRecord[0],
                Role = strRecord[1]
            });
        }
        // Find the person for the specified role
        FindPerson(lrp, this.RoleToFind.Text);
    }

    //Find the people for the specified role and add to the results textbox
    private void FindPerson(List<RolePerson> lrp, string strRole)
    {
        this.Result.Text = null;
        string strResults = string.Empty;
        foreach (RolePerson rp in lrp)
        {
            if (rp.Role == strRole)
                strResults = strResults + rp.Person + "\r\n";
        }
        this.Result.Text = strResults;
    }
}

结果:

Screen shot of the web page

使用上述内容,您可以找到同一角色中的多个人,并允许用户指定角色。

可以进一步开发FindPerson以使用Linq查询,这对于更大的字符串更有效。