Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Regex is the right tool for this. Use <a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html" rel="nofollow"><code>Pattern</code></a> and <a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html" rel="nofollow"><code>Matcher</code></a>.</p> <pre><code>public static String filter(String s, String open, String close){ Pattern p = Pattern.compile(Pattern.quote(open) + "(.*?)" + Pattern.quote(close)); Matcher m = p.matcher(s); StringBuilder filtered = new StringBuilder(); while (m.find()){ filtered.append(m.group(1)).append(", "); } return filtered.substring(0, filtered.length() - 2); //-2 because trailing ", " } </code></pre> <p><a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#quote%28java.lang.String%29" rel="nofollow"><code>Pattern.quote</code></a> ensures that any special characters for <code>open</code> and <code>close</code> are treated as regular ones.</p> <p><code>m.group()</code> returns the group from the last <code>String</code> matched by <code>m.find()</code>.</p> <p><code>m.find()</code> finds all substrings that match the regex.</p> <hr> <h2>Non-regex Solutions:</h2> <p>Note: in both of these, <code>end</code> is assigned <code>s.indexOf(close, start + 1)</code>, using <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf%28java.lang.String,%20int%29" rel="nofollow"><code>String#indexOf(String, int)</code></a> and <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#indexOf%28java.lang.String,%20int%29" rel="nofollow"><code>StringBuilder#indexOf(String, int)</code></a> so that even if the <code>open</code> and <code>close</code> values are the same, no error occurs.</p> <p><strong>Recursion</strong>:</p> <pre><code>public static String filter(String s, String open, String close){ int start = s.indexOf(open); int end = s.indexOf(close, start + 1); //I took the liberty of adding "String" and renaming your variable String get = s.substring(start + open.length(), end); s = s.substring(end + close.length()); if (s.indexOf(open) == -1){ return get; } return get + ", " + filter(s, open, close); } </code></pre> <p>Rather than adding the <code>", "</code> right off the bat, it is a little easier to deal with it later. Also, note that <code>s.substring(end + close.length(), s.length())</code> is the same as <code>s.substring(end + close.length());</code> Also, I feel that it is neater to see if <code>s.indexOf(...) == -1</code> rather than checking for <code>&gt;=0</code>. </p> <p>The real problem lies in the way you treat <code>filtered</code>. First of all, you need to declare <code>filtered</code> as type <code>String</code>. Next, since you are doing recursion, you shouldn't concatenate to <code>filtered</code>. That would make the line where we first see <code>filtered</code>: <code>String filtered = s.substring(start + open.length(), end) + ", ";</code>. If you fix that line, your solution works.</p> <p><strong>Iterative</strong>:</p> <pre><code>public static String filter(String str, String open, String close){ int open_length = open.length(); int close_length = close.length(); StringBuilder s = new StringBuilder(str); StringBuilder filtered = new StringBuilder(); for (int start = s.indexOf(open), end = s.indexOf(close, start + 1); start != -1; start = s.indexOf(open), end = s.indexOf(close, start + 1)){ filtered.append(s.substring(start + open_length, end)).append(", "); s.delete(0, end + close_length); } return filtered.substring(0, filtered.length() - 2); //trailing ", " } </code></pre> <p>This iterative method makes use of <code>StringBuilder</code>, but the same can be done without it. It makes two <code>StringBuilder</code>s, one empty one, and one that holds the value of the original <code>String</code>. In the <code>for</code> loop:</p> <ul> <li><code>int start = s.indexOf(open), end = s.indexOf(close)</code> gets a reference to the indices</li> <li><code>start != -1</code> ends the loop if <code>s</code> does not contain <code>open</code></li> <li><code>start = s.indexOf(open), end = s.indexOf(close)</code> after each iteration of the loop, find the indices again.</li> </ul> <p>The inside of the loop appends the correct substring to <code>finished</code> and removes the appended part from the other <code>StringBuilder</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload