如何在字符串中获取向量位置并将其存储为整数?

时间:2018-04-27 05:01:32

标签: c#

在SO上有很多这些问题,但是我没有通过将矢量坐标提取到整数值来找到这种情况。

我正在解析当前字符串:

  

“AT(1,1)ADDROOM RM0001”

我需要获取(#,#)之间的数字并将它们存储为整数。

我尝试的一个解决方案是获取第一个'('。读入字符串直到满足逗号,然后再次读取直到最后')'的索引。我尝试的另一个解决方案是找到','并在遇到括号之前获取字符串之前和之后。

我一直觉得这很容易出错。我觉得如果从字符串中读取,有一种更简单的方法。我在研究Regex。

5 个答案:

答案 0 :(得分:4)

这是你需要的正则表达式:

\((-?\d+)\s*,\s*(-?\d+)\)

你可以像这样使用它:

var match = Regex.Match("some string (1234, -5678)", @"\((-?\d+)\s*,\s*(-?\d+)\)")
var x = match.Groups[1].Value;
var y = match.Groups[2].Value;

xy将是向量的两个组成部分。

说明:

  • \(左括号
  • (-?\d+)首先捕获捕获向量第一个组成部分的组。 -是可选的(因此正和负整数都匹配)后跟一个或多个数字(\d)。同样的事情后来在正则表达式中再次出现以捕获第二个组件
  • \s*这允许数字和逗号之间的任意数量的空格
  • \)右括号

有关较低级别的说明,请转到https://regex101.com/r/PnwBJS/1并查看"解释"部分。

答案 1 :(得分:3)

这是一个简短的程序,分别捕获两个数字:

using System;    
using System.Text.RegularExpressions;

public class Test
{
    public static void Main()
    {
        string s = "AT (1,1) ADDROOM RM0001";
        Regex r = new Regex(@"\((\d+)[^\d]+(\d+)\)");
        MatchCollection mc = r.Matches(s);

        var firstNumber = mc[0].Groups[1].Value;
        var secondNumber = mc[0].Groups[2].Value;
    }
}

<强>解释

  • \(匹配左括号
  • (\d+)匹配一个数字;一个或多个数字
  • [^\d]+匹配非数字;一个或多个字符
  • (\d+)匹配一个数字;一个或多个数字
  • \)匹配关闭 括号

答案 2 :(得分:1)

好的Regex在这里是最简单的方法,但你无论如何都要过滤它,因为它会提取我想的括号外的数字(我不太了解Regex), private void createLayout() { ScrollView objScrollView = new ScrollView(this); ViewGroup.LayoutParams objLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT); objScrollView.setLayoutParams(objLayoutParams); RelativeLayout objParentLayout = new RelativeLayout(this); RelativeLayout.LayoutParams objParentParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); int intId = 100; int intLeft = 0; for (int i = 0; i < arrobjSeats.size(); i++) { Seat objSeat = arrobjSeats.get(i); RelativeLayout objItemLayout = new RelativeLayout(this); RelativeLayout.LayoutParams objItemParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); objItemParams.setMargins(objSeat.getIntTop() + 30, objSeat.getIntLeft() - 110, 0, 10); intLeft = objSeat.getIntTop(); ImageView imgSeat = new ImageView(this); imgSeat.setImageResource(R.drawable.ic_airline_seat_recline_normal_black_24dp); imgSeat.setColorFilter(Color.parseColor(objSeat.getStrSeatColor()), android.graphics.PorterDuff.Mode.SRC_IN); imgSeat.setPadding(5, 5, 10, 25); imgSeat.setId(intId++); RelativeLayout.LayoutParams objImageParams = new RelativeLayout.LayoutParams(120, 80); objImageParams.addRule(RelativeLayout.CENTER_HORIZONTAL); TextView txtSeatName = new TextView(this); RelativeLayout.LayoutParams objTextParams = new RelativeLayout.LayoutParams(120, RelativeLayout.LayoutParams.WRAP_CONTENT); objTextParams.addRule(RelativeLayout.ALIGN_BOTTOM, imgSeat.getId()); txtSeatName.setPadding(5, 10, 5, 5); txtSeatName.setTextColor(Color.parseColor(objSeat.getStrSeatColor())); txtSeatName.setText(objSeat.getStrSeatName()); txtSeatName.setGravity(Gravity.CENTER); txtSeatName.setTextSize(16); objItemLayout.setTag(i); objItemLayout.addView(imgSeat, objImageParams); objItemLayout.addView(txtSeatName, objTextParams); objItemLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int intPosition = (int) v.getTag(); Seat objSeat = arrobjSeats.get(intPosition); Toast.makeText(SeatActivity.this, "Seat=>" + objSeat.getIntSeatId() + "=>" + objSeat.getStrSeatName(), Toast.LENGTH_SHORT).show(); } }); objParentLayout.setBackgroundColor(Color.CYAN); objParentLayout.addView(objItemLayout, objItemParams); System.out.println("Final Color=>" + objSeat.getStrSeatColor()); } objScrollView.addView(objParentLayout, objParentParams); relativeLayout.addView(objScrollView); } 是一个整数的正则表达式数字,如果你决定这样。 另一种方法是您描述的只是过滤字符串然后将其解析为整数。 我能想到的最后一种方法是使用linq,然后解析为整数。

这是我为你的字符串做的正则表达式方法:

\d+

然后你只需要根据需要解析数组中的字符串。

答案 3 :(得分:1)

就正则表达式来说,这个案例看起来相当微不足道,但我知道正则表达式可能难以包围,所以我将详细介绍它。

在正则表达式中,数值可以由\d表示。我假设你想要捕获大于9的坐标,所以我们将使用\d+来捕获多个数字。

对于其余部分,逗号只是一个文字,并且在不在特定结构中使用时,它在正则表达式中没有任何特殊功能。 Unescaped brackets become capture groups,因此需要在\之前放置文字括号。这里需要两个捕获组,每个捕获组围绕一个数字。

这样,您的(#,#)作为正则表达式将成为\((\d+),(\d+)\)。文字开头括号,一个包含一个或多个数字字符的捕获组,一个文字逗号,另一个数字字符捕获组,最后是字面结束括号。

Test it out online

然后,它只是获取捕获组并将其解析为整数。请注意,由于我们100%确定这些组的内容是一个或多个数字符号,因此不需要TryParse,因此如果正则表达式匹配,则解析将始终成功。

    String str ="AT (1,1) ADDROOM RM0001";
    // Double all backslashes in the code, or prefix the quoted part with @
    Regex coords = new Regex("\\((\\d+),(\\d+)\\)");
    MatchCollection matches = coords.Matches(str);
    if (matches.Count > 0)
    {
        Int32 coord1 = Int32.Parse(matches[0].Groups[1].Value);
        Int32 coord2 = Int32.Parse(matches[0].Groups[2].Value);
        // Process the values...
    }

当然,如果要处理多个匹配项,可以使用foreach循环遍历MatchCollection的内容。

[编辑]

As pointed out by Sweeper,如果您想捕获正数和负数,捕获组应该变为(-?\d+)。问号表示一个可选组件,这意味着在它之前可以有0或1个文字-字符。这会给:

\((-?\d+),(-?\d+)\)

如果您想在这些坐标和括号/逗号之间留出空格,您还需要在组,括号和逗号之间添加一些\s**是一个修饰符(如+?),表示在它之前出现零个或多个元素。 \s是&#34;空白&#34;的简写,就像数字\d一样。

这个更宽松的版本将是

\(\s*(-?\d+)\s*,\s*(-?\d+)\s*\)

答案 4 :(得分:0)

假设你有任意数量的积分,你可以使用这样的东西。它几乎肯定不是很有效,但除非你处理它们,否则它可能并不重要:

const string s = "AT (35,200) ADDROOM RM0001";

var numbers = s.Split(' ')[1]
               .Replace("(", string.Empty)
               .Replace(")", string.Empty)
               .Split(',').Select(int.Parse);